library(data.table)
library(ggplot2)
library(lme4)
library(dplyr)

Attaching package: ‘dplyr’

The following objects are masked from ‘package:data.table’:

    between, first, last

The following objects are masked from ‘package:stats’:

    filter, lag

The following objects are masked from ‘package:base’:

    intersect, setdiff, setequal, union
load("~/Documents/grad school/Rutgers/LabWork/Colonization_Extinction/spp_master_ztemp.Rdata")

First, let’s get some regional statistics

#count colonizations by region
col <- spp_master_ztemp %>%
  group_by(reg) %>%
  summarise(sum(col))
#count extinctions by region
ext <- spp_master_ztemp %>%
  group_by(reg) %>%
  summarise(sum(now_ext))
#count observations by region
count <- spp_master_ztemp %>%
  group_by(reg) %>%
  summarise(n())
#first year
year.first <- spp_master_ztemp %>%
  group_by(reg) %>%
  summarise(min(year))
#last year
year.last <- spp_master_ztemp %>%
  group_by(reg) %>%
  summarise(max(year))
region_summaries <- cbind(count, col[,2], ext[,2], year.first[,2], year.last[,2])
colnames(region_summaries) <- c("reg", "n", "n.col", "n.ext", "year.first","year.last")

Now we’ll visualize regions in a plot

ggsave(plot = g, filename = "plots/occurence_plot.png")
Saving 7 x 7 in image
g

Now, let’s do the same process as we did in 04_24_19_Temp_link_traits_fish BUT region specific

Surface colonization comparison by region

Now, I’ll merge all surface colonization models

surface_colonization_model_comparison_byregion <- rbind(surface_colonization_model_comparison_ai, surface_colonization_model_comparison_ebs, surface_colonization_model_comparison_gmex, surface_colonization_model_comparison_goa, surface_colonization_model_comparison_neus, surface_colonization_model_comparison_newf, surface_colonization_model_comparison_sa, surface_colonization_model_comparison_shelf, surface_colonization_model_comparison_wctri)

Best surface colonization models per region

surface_colonization_model_comparison_byregion %>%
  filter(converge == TRUE, !grepl("mean", variable)) %>% #ignoring mean for now, and get rid of those that didn't converge
  group_by(reg) %>% #group by region
  arrange(AICc) %>% #arrange by AICc
  top_n(-5, AICc) #take 5 best models (lowest AICc)
NA

Bottom colonization comparison by region

  for (i in 1:length(bottom_variables)){
    mod <- glmer(col ~ get(bottom_variables[i]) + (1|year_factor), family = binomial, data = spp_master_ztemp[reg == "wctri"])
    bottom_colonization_model_comparison_wctri[i,variable := bottom_variables[i]]
    bottom_colonization_model_comparison_wctri[i,coef := coef(summary(mod))[,"Estimate"][2]]
    bottom_colonization_model_comparison_wctri[i,p_value := coef(summary(mod))[,"Pr(>|z|)"][2]]
    bottom_colonization_model_comparison_wctri[i,AICc := AICc(mod)]
    
    print(paste(i, length(bottom_variables), sep = "/"))
      
  }
[1] "1/124"
[1] "2/124"
[1] "3/124"
[1] "4/124"
[1] "5/124"
[1] "6/124"
[1] "7/124"
[1] "8/124"
[1] "9/124"
[1] "10/124"
[1] "11/124"
[1] "12/124"
[1] "13/124"
Model failed to converge with max|grad| = 0.0308063 (tol = 0.001, component 1)
[1] "14/124"
[1] "15/124"
[1] "16/124"
[1] "17/124"
[1] "18/124"
[1] "19/124"
[1] "20/124"
[1] "21/124"
[1] "22/124"
Model failed to converge with max|grad| = 0.0296878 (tol = 0.001, component 1)
[1] "23/124"
[1] "24/124"
[1] "25/124"
[1] "26/124"
[1] "27/124"
[1] "28/124"
[1] "29/124"
[1] "30/124"
[1] "31/124"
[1] "32/124"
Model failed to converge with max|grad| = 0.0298623 (tol = 0.001, component 1)
[1] "33/124"
[1] "34/124"
[1] "35/124"
[1] "36/124"
[1] "37/124"
[1] "38/124"
[1] "39/124"
[1] "40/124"
[1] "41/124"
[1] "42/124"
[1] "43/124"
[1] "44/124"
[1] "45/124"
[1] "46/124"
[1] "47/124"
[1] "48/124"
Model failed to converge with max|grad| = 0.0288633 (tol = 0.001, component 1)
[1] "49/124"
[1] "50/124"
Model failed to converge with max|grad| = 0.0268189 (tol = 0.001, component 1)
[1] "51/124"
Model failed to converge with max|grad| = 0.0266311 (tol = 0.001, component 1)
[1] "52/124"
[1] "53/124"
[1] "54/124"
[1] "55/124"
Model failed to converge with max|grad| = 0.0268531 (tol = 0.001, component 1)
[1] "56/124"
[1] "57/124"
Model failed to converge with max|grad| = 0.028596 (tol = 0.001, component 1)
[1] "58/124"
[1] "59/124"
Model failed to converge with max|grad| = 0.0282459 (tol = 0.001, component 1)
[1] "60/124"
[1] "61/124"
[1] "62/124"
[1] "63/124"
[1] "64/124"
Model failed to converge with max|grad| = 0.0304929 (tol = 0.001, component 1)
[1] "65/124"
[1] "66/124"
[1] "67/124"
[1] "68/124"
[1] "69/124"
[1] "70/124"
[1] "71/124"
[1] "72/124"
[1] "73/124"
[1] "74/124"
[1] "75/124"
Model failed to converge with max|grad| = 0.0316174 (tol = 0.001, component 1)
[1] "76/124"
[1] "77/124"
Model failed to converge with max|grad| = 0.0261989 (tol = 0.001, component 1)
[1] "78/124"
[1] "79/124"
[1] "80/124"
[1] "81/124"
[1] "82/124"
[1] "83/124"
[1] "84/124"
[1] "85/124"
[1] "86/124"
[1] "87/124"
[1] "88/124"
Model failed to converge with max|grad| = 0.0309174 (tol = 0.001, component 1)
[1] "89/124"
[1] "90/124"
[1] "91/124"
[1] "92/124"
Model failed to converge with max|grad| = 0.029357 (tol = 0.001, component 1)
[1] "93/124"
[1] "94/124"
[1] "95/124"
[1] "96/124"
[1] "97/124"
Model failed to converge with max|grad| = 0.0290942 (tol = 0.001, component 1)
[1] "98/124"
[1] "99/124"
[1] "100/124"
[1] "101/124"
[1] "102/124"
[1] "103/124"
Model failed to converge with max|grad| = 0.0294299 (tol = 0.001, component 1)
[1] "104/124"
[1] "105/124"
[1] "106/124"
[1] "107/124"
[1] "108/124"
Model failed to converge with max|grad| = 0.0313106 (tol = 0.001, component 1)
[1] "109/124"
[1] "110/124"
[1] "111/124"
Model failed to converge with max|grad| = 0.0295465 (tol = 0.001, component 1)
[1] "112/124"
Model failed to converge with max|grad| = 0.0314474 (tol = 0.001, component 1)
[1] "113/124"
[1] "114/124"
Model failed to converge with max|grad| = 0.0247102 (tol = 0.001, component 1)
[1] "115/124"
[1] "116/124"
[1] "117/124"
[1] "118/124"
Model failed to converge with max|grad| = 0.0251905 (tol = 0.001, component 1)
[1] "119/124"
[1] "120/124"
[1] "121/124"
[1] "122/124"
[1] "123/124"
[1] "124/124"

Now, I’ll merge all bottom colonization models

bottom_colonization_model_comparison_byregion <- rbind(bottom_colonization_model_comparison_ai, bottom_colonization_model_comparison_ebs, bottom_colonization_model_comparison_gmex, bottom_colonization_model_comparison_goa, bottom_colonization_model_comparison_neus, bottom_colonization_model_comparison_newf, bottom_colonization_model_comparison_sa, bottom_colonization_model_comparison_shelf, bottom_colonization_model_comparison_wctri)

Best bottom colonization models per region


Surface extinction comparison by region

Now, I’ll merge all surface extinction models

surface_extinction_model_comparison_byregion <- rbind(surface_extinction_model_comparison_ai, surface_extinction_model_comparison_ebs, surface_extinction_model_comparison_gmex, surface_extinction_model_comparison_goa, surface_extinction_model_comparison_neus, surface_extinction_model_comparison_newf, surface_extinction_model_comparison_sa, surface_extinction_model_comparison_shelf, surface_extinction_model_comparison_wctri)

Best surface extinction models per region

surface_extinction_model_comparison_byregion %>%
  filter(converge == TRUE, !grepl("mean", variable)) %>% #ignoring mean for now, and get rid of those that didn't converge
  group_by(reg) %>% #group by region
  arrange(AICc) %>% #arrange by AICc
  top_n(-5, AICc) #take 5 best models (lowest AICc)
  

Bottom extinction comparison by region

bottom_variables <- colnames(spp_master_ztemp[,169:292])
  
#regions

#ai (1:3, 15, 24, 44, 45, 47, 55, 57 fail to converge)
bottom_extinction_model_comparison_ai <- as.data.table(matrix(nrow = length(bottom_variables)))
bottom_extinction_model_comparison_ai[, variable:=as.factor(V1)][, coef:=as.numeric(V1)][, p_value:=as.numeric(V1)][, AICc:=as.numeric(V1)]
bottom_extinction_model_comparison_ai[, V1 := NULL]
  
  for (i in 1:length(bottom_variables)){
    mod <- glmer(now_ext ~ get(bottom_variables[i]) + (1|year_factor), family = binomial, data = spp_master_ztemp[reg == "ai"])
    bottom_extinction_model_comparison_ai[i,variable := bottom_variables[i]]
    bottom_extinction_model_comparison_ai[i,coef := coef(summary(mod))[,"Estimate"][2]]
    bottom_extinction_model_comparison_ai[i,p_value := coef(summary(mod))[,"Pr(>|z|)"][2]]
    bottom_extinction_model_comparison_ai[i,AICc := AICc(mod)]
    
    print(paste(i, length(bottom_variables), sep = "/"))
      
  }
  #add column for those that didn't converge
  bottom_extinction_model_comparison_ai$converge <- T
  bottom_extinction_model_comparison_ai$converge[c(1:3, 15, 24, 44, 45, 47, 55, 57)] <- F
  
  #add column to designate region 
  bottom_extinction_model_comparison_ai$reg <- "ai"
  
#ebs (23 did not converge)

bottom_extinction_model_comparison_ebs <- as.data.table(matrix(nrow = length(bottom_variables)))
bottom_extinction_model_comparison_ebs[, variable:=as.factor(V1)][, coef:=as.numeric(V1)][, p_value:=as.numeric(V1)][, AICc:=as.numeric(V1)]
bottom_extinction_model_comparison_ebs[, V1 := NULL]
  
  for (i in 1:length(bottom_variables)){
    mod <- glmer(now_ext ~ get(bottom_variables[i]) + (1|year_factor), family = binomial, data = spp_master_ztemp[reg == "ebs"])
    bottom_extinction_model_comparison_ebs[i,variable := bottom_variables[i]]
    bottom_extinction_model_comparison_ebs[i,coef := coef(summary(mod))[,"Estimate"][2]]
    bottom_extinction_model_comparison_ebs[i,p_value := coef(summary(mod))[,"Pr(>|z|)"][2]]
    bottom_extinction_model_comparison_ebs[i,AICc := AICc(mod)]
    
    print(paste(i, length(bottom_variables), sep = "/"))
      
  }
  #add column for those that didn't converge
  bottom_extinction_model_comparison_ebs$converge <- T
  bottom_extinction_model_comparison_ebs$converge[c(23)] <- F
  
  #add column to designate region 
  bottom_extinction_model_comparison_ebs$reg <- "ebs"
  
#gmex (5, 6, 7, 8, 13, 15, 17, 18, 20, 21, 23, 24, 25, 27, 28, 31, 32, 34, 36, 40:44, 46:48, 52, 56, 57, 60, 61, 63, 67, 70, 75, 80, 90, 92, 99, 110, 113,  fail to converge)

bottom_extinction_model_comparison_gmex <- as.data.table(matrix(nrow = length(bottom_variables)))
bottom_extinction_model_comparison_gmex[, variable:=as.factor(V1)][, coef:=as.numeric(V1)][, p_value:=as.numeric(V1)][, AICc:=as.numeric(V1)]
bottom_extinction_model_comparison_gmex[, V1 := NULL]
  
  for (i in 1:length(bottom_variables)){
    mod <- glmer(now_ext ~ get(bottom_variables[i]) + (1|year_factor), family = binomial, data = spp_master_ztemp[reg == "gmex"])
    mod1 <- glmer(now_ext ~ get(bottom_variables[i]) + (1|year_factor), family = binomial, data = spp_master_ztemp[reg == "gmex"])
    bottom_extinction_model_comparison_gmex[i,variable := bottom_variables[i]]
    bottom_extinction_model_comparison_gmex[i,coef := coef(summary(mod))[,"Estimate"][2]]
    bottom_extinction_model_comparison_gmex[i,p_value := coef(summary(mod))[,"Pr(>|z|)"][2]]
    bottom_extinction_model_comparison_gmex[i,AICc := AICc(mod)]
    
    print(paste(i, length(bottom_variables), sep = "/"))
      
  }
  #add column for those that didn't converge
  bottom_extinction_model_comparison_gmex$converge <- T
  bottom_extinction_model_comparison_gmex$converge[c(5, 6, 7, 8, 13, 15, 17, 18, 20, 21, 23, 24, 25, 27, 28, 31, 32, 34, 36, 40:44, 46:48, 52, 56, 57, 60, 61, 63, 67, 70, 75, 80, 90, 92, 99, 110, 113)] <- F
  
  #add column to designate region 
  bottom_extinction_model_comparison_gmex$reg <- "gmex"

#goa (62 doesn't converge)

bottom_extinction_model_comparison_goa <- as.data.table(matrix(nrow = length(bottom_variables)))
bottom_extinction_model_comparison_goa[, variable:=as.factor(V1)][, coef:=as.numeric(V1)][, p_value:=as.numeric(V1)][, AICc:=as.numeric(V1)]
bottom_extinction_model_comparison_goa[, V1 := NULL]
  
  for (i in 1:length(bottom_variables)){
    mod <- glmer(now_ext ~ get(bottom_variables[i]) + (1|year_factor), family = binomial, data = spp_master_ztemp[reg == "goa"])
    bottom_extinction_model_comparison_goa[i,variable := bottom_variables[i]]
    bottom_extinction_model_comparison_goa[i,coef := coef(summary(mod))[,"Estimate"][2]]
    bottom_extinction_model_comparison_goa[i,p_value := coef(summary(mod))[,"Pr(>|z|)"][2]]
    bottom_extinction_model_comparison_goa[i,AICc := AICc(mod)]
    
    print(paste(i, length(bottom_variables), sep = "/"))
      
  }
  #add column for those that didn't converge
  bottom_extinction_model_comparison_goa$converge <- T
  bottom_extinction_model_comparison_goa$converge[c(62)] <- T
  
  #add column to designate region 
  bottom_extinction_model_comparison_goa$reg <- "goa"

#neus (1, 4, 9, 10, 12, 16:19, 22, 24, 27, 28, 29, 32, 33, 36, 37, 39, 40, 43,  failed to converge)

bottom_extinction_model_comparison_neus <- as.data.table(matrix(nrow = length(bottom_variables)))
bottom_extinction_model_comparison_neus[, variable:=as.factor(V1)][, coef:=as.numeric(V1)][, p_value:=as.numeric(V1)][, AICc:=as.numeric(V1)]
bottom_extinction_model_comparison_neus[, V1 := NULL]
  
  for (i in 1:length(bottom_variables)){
    mod <- glmer(now_ext ~ get(bottom_variables[i]) + (1|year_factor), family = binomial, data = spp_master_ztemp[reg == "neus"])
    bottom_extinction_model_comparison_neus[i,variable := bottom_variables[i]]
    bottom_extinction_model_comparison_neus[i,coef := coef(summary(mod))[,"Estimate"][2]]
    bottom_extinction_model_comparison_neus[i,p_value := coef(summary(mod))[,"Pr(>|z|)"][2]]
    bottom_extinction_model_comparison_neus[i,AICc := AICc(mod)]
    
    print(paste(i, length(bottom_variables), sep = "/"))
      
  }
#add column for those that didn't converge
bottom_extinction_model_comparison_neus$converge <- T
bottom_extinction_model_comparison_neus$converge[c(1, 4, 9, 10, 12, 16:19, 22, 24, 27, 28, 29, 32, 33, 36, 37, 39, 40, 43)] <- F

#add column to designate region 
  bottom_extinction_model_comparison_neus$reg <- "neus"

#newf (ALL failed to converge (all singularities) )

bottom_extinction_model_comparison_newf <- as.data.table(matrix(nrow = length(bottom_variables)))
bottom_extinction_model_comparison_newf[, variable:=as.factor(V1)][, coef:=as.numeric(V1)][, p_value:=as.numeric(V1)][, AICc:=as.numeric(V1)]
bottom_extinction_model_comparison_newf[, V1 := NULL]
  
  for (i in 1:length(bottom_variables)){
    mod <- glmer(now_ext ~ get(bottom_variables[i]) + (1|year_factor), family = binomial, data = spp_master_ztemp[reg == "newf"])
    bottom_extinction_model_comparison_newf[i,variable := bottom_variables[i]]
    bottom_extinction_model_comparison_newf[i,coef := coef(summary(mod))[,"Estimate"][2]]
    bottom_extinction_model_comparison_newf[i,p_value := coef(summary(mod))[,"Pr(>|z|)"][2]]
    bottom_extinction_model_comparison_newf[i,AICc := AICc(mod)]
    
    print(paste(i, length(bottom_variables), sep = "/"))
      
  }

#add column for those that didn't converge
bottom_extinction_model_comparison_newf$converge <- T
bottom_extinction_model_comparison_newf$converge[c(1:124)] <- F

#add column to designate region 
  bottom_extinction_model_comparison_newf$reg <- "newf"


#shelf (none didn't converge)

bottom_extinction_model_comparison_shelf <- as.data.table(matrix(nrow = length(bottom_variables)))
bottom_extinction_model_comparison_shelf[, variable:=as.factor(V1)][, coef:=as.numeric(V1)][, p_value:=as.numeric(V1)][, AICc:=as.numeric(V1)]
bottom_extinction_model_comparison_shelf[, V1 := NULL]
  
  for (i in 1:length(bottom_variables)){
    mod <- glmer(now_ext ~ get(bottom_variables[i]) + (1|year_factor), family = binomial, data = spp_master_ztemp[reg == "shelf"])
    bottom_extinction_model_comparison_shelf[i,variable := bottom_variables[i]]
    bottom_extinction_model_comparison_shelf[i,coef := coef(summary(mod))[,"Estimate"][2]]
    bottom_extinction_model_comparison_shelf[i,p_value := coef(summary(mod))[,"Pr(>|z|)"][2]]
    bottom_extinction_model_comparison_shelf[i,AICc := AICc(mod)]
    
    print(paste(i, length(bottom_variables), sep = "/"))
      
  }

#add column for those that didn't converge
bottom_extinction_model_comparison_shelf$converge <- T

#add column to designate region 
  bottom_extinction_model_comparison_shelf$reg <- "shelf"


#sa (12, 31, 35, 55, 63, 72, 82, 87, 92, 96, 123 didn't converge)

bottom_extinction_model_comparison_sa <- as.data.table(matrix(nrow = length(bottom_variables)))
bottom_extinction_model_comparison_sa[, variable:=as.factor(V1)][, coef:=as.numeric(V1)][, p_value:=as.numeric(V1)][, AICc:=as.numeric(V1)]
bottom_extinction_model_comparison_sa[, V1 := NULL]
  
  for (i in 1:length(bottom_variables)){
    mod <- glmer(now_ext ~ get(bottom_variables[i]) + (1|year_factor), family = binomial, data = spp_master_ztemp[reg == "sa"])
    bottom_extinction_model_comparison_sa[i,variable := bottom_variables[i]]
    bottom_extinction_model_comparison_sa[i,coef := coef(summary(mod))[,"Estimate"][2]]
    bottom_extinction_model_comparison_sa[i,p_value := coef(summary(mod))[,"Pr(>|z|)"][2]]
    bottom_extinction_model_comparison_sa[i,AICc := AICc(mod)]
    
    print(paste(i, length(bottom_variables), sep = "/"))
      
  }

#add column for those that didn't converge
bottom_extinction_model_comparison_sa$converge <- T
bottom_extinction_model_comparison_sa$converge[c(12, 31, 35, 55, 63, 72, 82, 87, 92, 96, 123)] <- F

#add column to designate region 
  bottom_extinction_model_comparison_sa$reg <- "sa"


#wctri (1, 2, 3, 5:10, 15:20, 25:29, 36, 38:42, 44, 47, 49, 52, 54, 55, 56, 58:65, 68:75, 79: 83, 85:87, 89, 90, 94:98, 100, 102:106, 109:111, 113:116, 119, 121, 124 failed to converge)

bottom_extinction_model_comparison_wctri <- as.data.table(matrix(nrow = length(bottom_variables)))
bottom_extinction_model_comparison_wctri[, variable:=as.factor(V1)][, coef:=as.numeric(V1)][, p_value:=as.numeric(V1)][, AICc:=as.numeric(V1)]
bottom_extinction_model_comparison_wctri[, V1 := NULL]
  
  for (i in 1:length(bottom_variables)){
    mod <- glmer(now_ext ~ get(bottom_variables[i]) + (1|year_factor), family = binomial, data = spp_master_ztemp[reg == "wctri"])
    bottom_extinction_model_comparison_wctri[i,variable := bottom_variables[i]]
    bottom_extinction_model_comparison_wctri[i,coef := coef(summary(mod))[,"Estimate"][2]]
    bottom_extinction_model_comparison_wctri[i,p_value := coef(summary(mod))[,"Pr(>|z|)"][2]]
    bottom_extinction_model_comparison_wctri[i,AICc := AICc(mod)]
    
    print(paste(i, length(bottom_variables), sep = "/"))
      
  }

#add column for those that didn't converge
bottom_extinction_model_comparison_wctri$converge <- T
bottom_extinction_model_comparison_wctri$converge[c(1, 2, 3, 5:10, 15:20, 25:29, 36, 38:42, 44, 47, 49, 52, 54, 55, 56, 58:65, 68:75, 79: 83, 85:87, 89, 90, 94:98, 100, 102:106, 109:111, 113:116, 119, 121, 124)] <- F

#add column to designate region 
  bottom_extinction_model_comparison_wctri$reg <- "wctri"

Now, I’ll merge all bottom extinction models

bottom_extinction_model_comparison_byregion <- rbind(bottom_extinction_model_comparison_ai, bottom_extinction_model_comparison_ebs, bottom_extinction_model_comparison_gmex, bottom_extinction_model_comparison_goa, bottom_extinction_model_comparison_neus, bottom_extinction_model_comparison_newf, bottom_extinction_model_comparison_sa, bottom_extinction_model_comparison_shelf, bottom_extinction_model_comparison_wctri)

Best bottom extinction models per region

LS0tCnRpdGxlOiAiQ29sIEV4dCBieSBSZWdpb24iCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KYGBge3Igc2V0dXB9CgpsaWJyYXJ5KGRhdGEudGFibGUpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShsbWU0KQpsaWJyYXJ5KGRwbHlyKQoKbG9hZCgifi9Eb2N1bWVudHMvZ3JhZCBzY2hvb2wvUnV0Z2Vycy9MYWJXb3JrL0NvbG9uaXphdGlvbl9FeHRpbmN0aW9uL3NwcF9tYXN0ZXJfenRlbXAuUmRhdGEiKQoKYGBgCkZpcnN0LCBsZXQncyBnZXQgc29tZSByZWdpb25hbCBzdGF0aXN0aWNzCmBgYHtyIHJlZ2lvbmFsIHN0YXRzfQojY291bnQgY29sb25pemF0aW9ucyBieSByZWdpb24KY29sIDwtIHNwcF9tYXN0ZXJfenRlbXAgJT4lCiAgZ3JvdXBfYnkocmVnKSAlPiUKICBzdW1tYXJpc2Uoc3VtKGNvbCkpCgojY291bnQgZXh0aW5jdGlvbnMgYnkgcmVnaW9uCmV4dCA8LSBzcHBfbWFzdGVyX3p0ZW1wICU+JQogIGdyb3VwX2J5KHJlZykgJT4lCiAgc3VtbWFyaXNlKHN1bShub3dfZXh0KSkKCiNjb3VudCBvYnNlcnZhdGlvbnMgYnkgcmVnaW9uCmNvdW50IDwtIHNwcF9tYXN0ZXJfenRlbXAgJT4lCiAgZ3JvdXBfYnkocmVnKSAlPiUKICBzdW1tYXJpc2UobigpKQoKI2ZpcnN0IHllYXIKeWVhci5maXJzdCA8LSBzcHBfbWFzdGVyX3p0ZW1wICU+JQogIGdyb3VwX2J5KHJlZykgJT4lCiAgc3VtbWFyaXNlKG1pbih5ZWFyKSkKI2xhc3QgeWVhcgp5ZWFyLmxhc3QgPC0gc3BwX21hc3Rlcl96dGVtcCAlPiUKICBncm91cF9ieShyZWcpICU+JQogIHN1bW1hcmlzZShtYXgoeWVhcikpCgpyZWdpb25fc3VtbWFyaWVzIDwtIGNiaW5kKGNvdW50LCBjb2xbLDJdLCBleHRbLDJdLCB5ZWFyLmZpcnN0WywyXSwgeWVhci5sYXN0WywyXSkKY29sbmFtZXMocmVnaW9uX3N1bW1hcmllcykgPC0gYygicmVnIiwgIm4iLCAibi5jb2wiLCAibi5leHQiLCAieWVhci5maXJzdCIsInllYXIubGFzdCIpCmBgYApOb3cgd2UnbGwgdmlzdWFsaXplIHJlZ2lvbnMgaW4gYSBwbG90CmBgYHtyIHJlZ2lvbiBwbG90fQojbWFuaXB1bGF0ZSBkYXRhCnJlZ2lvbl9zdW1tYXJpZXMubSA8LSBtZWx0KHJlZ2lvbl9zdW1tYXJpZXNbLDE6NF0sIGlkLnZhcnMgPSAicmVnIikKCmcgPC0gZ2dwbG90KGFlcyh4PXJlZywgeSA9IHZhbHVlLCBmaWxsID0gdmFyaWFibGUpLCBkYXRhID0gcmVnaW9uX3N1bW1hcmllcy5tKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIikgKwogIGxhYnMoeCA9ICJSZWdpb24iLCB5ID0gIkNvdW50cyIpCgoKZ2dzYXZlKHBsb3QgPSBnLCBmaWxlbmFtZSA9ICJwbG90cy9vY2N1cmVuY2VfcGxvdC5wbmciKQoKZwoKYGBgCgpOb3csIGxldCdzIGRvIHRoZSBzYW1lIHByb2Nlc3MgYXMgd2UgZGlkIGluIDA0XzI0XzE5X1RlbXBfbGlua190cmFpdHNfZmlzaCBCVVQgcmVnaW9uIHNwZWNpZmljCgojU3VyZmFjZSBjb2xvbml6YXRpb24gY29tcGFyaXNvbiBieSByZWdpb24KYGBge3Igc3VyZmFjZSBjb2xvbml6YXRpb24gY29tcGFyaXNvbiBieSByZWdpb259CiNwbGF5aW5nIHdpdGggeWVhciBhcyBmYWN0b3IKc3BwX21hc3Rlcl96dGVtcFsseWVhcl9mYWN0b3IgOj0gYXMuZmFjdG9yKHllYXIpXQoKc3VyZmFjZV92YXJpYWJsZXMgPC0gY29sbmFtZXMoc3BwX21hc3Rlcl96dGVtcFssNDU6MTY4XSkKICAKI3JlZ2lvbnMKCiNhaSAoMTcsIDUwLCA1MSwgNzUgZmFpbCB0byBjb252ZXJnZSkKc3VyZmFjZV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9haSA8LSBhcy5kYXRhLnRhYmxlKG1hdHJpeChucm93ID0gbGVuZ3RoKHN1cmZhY2VfdmFyaWFibGVzKSkpCnN1cmZhY2VfY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fYWlbLCB2YXJpYWJsZTo9YXMuZmFjdG9yKFYxKV1bLCBjb2VmOj1hcy5udW1lcmljKFYxKV1bLCBwX3ZhbHVlOj1hcy5udW1lcmljKFYxKV1bLCBBSUNjOj1hcy5udW1lcmljKFYxKV0Kc3VyZmFjZV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9haVssIFYxIDo9IE5VTExdCiAgCiAgZm9yIChpIGluIDE6bGVuZ3RoKHN1cmZhY2VfdmFyaWFibGVzKSl7CiAgICBtb2QgPC0gZ2xtZXIoY29sIH4gZ2V0KHN1cmZhY2VfdmFyaWFibGVzW2ldKSArICgxfHllYXJfZmFjdG9yKSwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBzcHBfbWFzdGVyX3p0ZW1wW3JlZyA9PSAiYWkiXSkKICAgIHN1cmZhY2VfY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fYWlbaSx2YXJpYWJsZSA6PSBzdXJmYWNlX3ZhcmlhYmxlc1tpXV0KICAgIHN1cmZhY2VfY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fYWlbaSxjb2VmIDo9IGNvZWYoc3VtbWFyeShtb2QpKVssIkVzdGltYXRlIl1bMl1dCiAgICBzdXJmYWNlX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX2FpW2kscF92YWx1ZSA6PSBjb2VmKHN1bW1hcnkobW9kKSlbLCJQcig+fHp8KSJdWzJdXQogICAgc3VyZmFjZV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9haVtpLEFJQ2MgOj0gQUlDYyhtb2QpXQogICAgCiAgICBwcmludChwYXN0ZShpLCBsZW5ndGgoc3VyZmFjZV92YXJpYWJsZXMpLCBzZXAgPSAiLyIpKQogICAgICAKICB9CiAgI2FkZCBjb2x1bW4gZm9yIHRob3NlIHRoYXQgZGlkbid0IGNvbnZlcmdlCiAgc3VyZmFjZV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9haSRjb252ZXJnZSA8LSBUCiAgc3VyZmFjZV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9haSRjb252ZXJnZVtjKDE3LCA1MCwgNTEsIDc1KV0gPC0gRgogIAogICNhZGQgY29sdW1uIHRvIGRlc2lnbmF0ZSByZWdpb24gCiAgc3VyZmFjZV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9haSRyZWcgPC0gImFpIgojZWJzICgxNCBkaWQgbm90IGNvbnZlcmdlKQoKc3VyZmFjZV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9lYnMgPC0gYXMuZGF0YS50YWJsZShtYXRyaXgobnJvdyA9IGxlbmd0aChzdXJmYWNlX3ZhcmlhYmxlcykpKQpzdXJmYWNlX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX2Vic1ssIHZhcmlhYmxlOj1hcy5mYWN0b3IoVjEpXVssIGNvZWY6PWFzLm51bWVyaWMoVjEpXVssIHBfdmFsdWU6PWFzLm51bWVyaWMoVjEpXVssIEFJQ2M6PWFzLm51bWVyaWMoVjEpXQpzdXJmYWNlX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX2Vic1ssIFYxIDo9IE5VTExdCiAgCiAgZm9yIChpIGluIDE6bGVuZ3RoKHN1cmZhY2VfdmFyaWFibGVzKSl7CiAgICBtb2QgPC0gZ2xtZXIoY29sIH4gZ2V0KHN1cmZhY2VfdmFyaWFibGVzW2ldKSArICgxfHllYXJfZmFjdG9yKSwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBzcHBfbWFzdGVyX3p0ZW1wW3JlZyA9PSAiZWJzIl0pCiAgICBzdXJmYWNlX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX2Vic1tpLHZhcmlhYmxlIDo9IHN1cmZhY2VfdmFyaWFibGVzW2ldXQogICAgc3VyZmFjZV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9lYnNbaSxjb2VmIDo9IGNvZWYoc3VtbWFyeShtb2QpKVssIkVzdGltYXRlIl1bMl1dCiAgICBzdXJmYWNlX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX2Vic1tpLHBfdmFsdWUgOj0gY29lZihzdW1tYXJ5KG1vZCkpWywiUHIoPnx6fCkiXVsyXV0KICAgIHN1cmZhY2VfY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fZWJzW2ksQUlDYyA6PSBBSUNjKG1vZCldCiAgICAKICAgIHByaW50KHBhc3RlKGksIGxlbmd0aChzdXJmYWNlX3ZhcmlhYmxlcyksIHNlcCA9ICIvIikpCiAgICAgIAogIH0KICAjYWRkIGNvbHVtbiBmb3IgdGhvc2UgdGhhdCBkaWRuJ3QgY29udmVyZ2UKICBzdXJmYWNlX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX2VicyRjb252ZXJnZSA8LSBUCiAgc3VyZmFjZV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9lYnMkY29udmVyZ2VbYygxNCldIDwtIEYKICAKICAjYWRkIGNvbHVtbiB0byBkZXNpZ25hdGUgcmVnaW9uIAogIHN1cmZhY2VfY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fZWJzJHJlZyA8LSAiZWJzIgogIAojZ21leCAoMTozMCBmYWlsIHRvIGNvbnZlcmdlKQoKc3VyZmFjZV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9nbWV4IDwtIGFzLmRhdGEudGFibGUobWF0cml4KG5yb3cgPSBsZW5ndGgoc3VyZmFjZV92YXJpYWJsZXMpKSkKc3VyZmFjZV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9nbWV4WywgdmFyaWFibGU6PWFzLmZhY3RvcihWMSldWywgY29lZjo9YXMubnVtZXJpYyhWMSldWywgcF92YWx1ZTo9YXMubnVtZXJpYyhWMSldWywgQUlDYzo9YXMubnVtZXJpYyhWMSldCnN1cmZhY2VfY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fZ21leFssIFYxIDo9IE5VTExdCiAgCiAgZm9yIChpIGluIDE6bGVuZ3RoKHN1cmZhY2VfdmFyaWFibGVzKSl7CiAgICBtb2QgPC0gZ2xtZXIoY29sIH4gZ2V0KHN1cmZhY2VfdmFyaWFibGVzW2ldKSArICgxfHllYXJfZmFjdG9yKSwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBzcHBfbWFzdGVyX3p0ZW1wW3JlZyA9PSAiZ21leCJdKQogICAgbW9kMSA8LSBnbG1lcihjb2wgfiBnZXQoc3VyZmFjZV92YXJpYWJsZXNbaV0pICsgKDF8eWVhcl9mYWN0b3IpLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IHNwcF9tYXN0ZXJfenRlbXBbcmVnID09ICJnbWV4Il0pCiAgICBzdXJmYWNlX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX2dtZXhbaSx2YXJpYWJsZSA6PSBzdXJmYWNlX3ZhcmlhYmxlc1tpXV0KICAgIHN1cmZhY2VfY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fZ21leFtpLGNvZWYgOj0gY29lZihzdW1tYXJ5KG1vZCkpWywiRXN0aW1hdGUiXVsyXV0KICAgIHN1cmZhY2VfY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fZ21leFtpLHBfdmFsdWUgOj0gY29lZihzdW1tYXJ5KG1vZCkpWywiUHIoPnx6fCkiXVsyXV0KICAgIHN1cmZhY2VfY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fZ21leFtpLEFJQ2MgOj0gQUlDYyhtb2QpXQogICAgCiAgICBwcmludChwYXN0ZShpLCBsZW5ndGgoc3VyZmFjZV92YXJpYWJsZXMpLCBzZXAgPSAiLyIpKQogICAgICAKICB9CiAgI2FkZCBjb2x1bW4gZm9yIHRob3NlIHRoYXQgZGlkbid0IGNvbnZlcmdlCiAgc3VyZmFjZV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9nbWV4JGNvbnZlcmdlIDwtIFQKICBzdXJmYWNlX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX2dtZXgkY29udmVyZ2VbYygxOjMwKV0gPC0gRgogIAogICNhZGQgY29sdW1uIHRvIGRlc2lnbmF0ZSByZWdpb24gCiAgc3VyZmFjZV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9nbWV4JHJlZyA8LSAiZ21leCIKCiNnb2EKCnN1cmZhY2VfY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fZ29hIDwtIGFzLmRhdGEudGFibGUobWF0cml4KG5yb3cgPSBsZW5ndGgoc3VyZmFjZV92YXJpYWJsZXMpKSkKc3VyZmFjZV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9nb2FbLCB2YXJpYWJsZTo9YXMuZmFjdG9yKFYxKV1bLCBjb2VmOj1hcy5udW1lcmljKFYxKV1bLCBwX3ZhbHVlOj1hcy5udW1lcmljKFYxKV1bLCBBSUNjOj1hcy5udW1lcmljKFYxKV0Kc3VyZmFjZV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9nb2FbLCBWMSA6PSBOVUxMXQogIAogIGZvciAoaSBpbiAxOmxlbmd0aChzdXJmYWNlX3ZhcmlhYmxlcykpewogICAgbW9kIDwtIGdsbWVyKGNvbCB+IGdldChzdXJmYWNlX3ZhcmlhYmxlc1tpXSkgKyAoMXx5ZWFyX2ZhY3RvciksIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gc3BwX21hc3Rlcl96dGVtcFtyZWcgPT0gImdvYSJdKQogICAgc3VyZmFjZV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9nb2FbaSx2YXJpYWJsZSA6PSBzdXJmYWNlX3ZhcmlhYmxlc1tpXV0KICAgIHN1cmZhY2VfY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fZ29hW2ksY29lZiA6PSBjb2VmKHN1bW1hcnkobW9kKSlbLCJFc3RpbWF0ZSJdWzJdXQogICAgc3VyZmFjZV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9nb2FbaSxwX3ZhbHVlIDo9IGNvZWYoc3VtbWFyeShtb2QpKVssIlByKD58enwpIl1bMl1dCiAgICBzdXJmYWNlX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX2dvYVtpLEFJQ2MgOj0gQUlDYyhtb2QpXQogICAgCiAgICBwcmludChwYXN0ZShpLCBsZW5ndGgoc3VyZmFjZV92YXJpYWJsZXMpLCBzZXAgPSAiLyIpKQogICAgICAKICB9CiAgI2FkZCBjb2x1bW4gZm9yIHRob3NlIHRoYXQgZGlkbid0IGNvbnZlcmdlCiAgc3VyZmFjZV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9nb2EkY29udmVyZ2UgPC0gVAogIAogICNhZGQgY29sdW1uIHRvIGRlc2lnbmF0ZSByZWdpb24gCiAgc3VyZmFjZV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9nb2EkcmVnIDwtICJnb2EiCgojbmV1cyAoMSwgNjo4LCAxMiwgMTUsIDE3LCAyMSwgMjMsIDMzLCAzNjo0MCBmYWlsZWQgdG8gY29udmVyZ2UpCgpzdXJmYWNlX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX25ldXMgPC0gYXMuZGF0YS50YWJsZShtYXRyaXgobnJvdyA9IGxlbmd0aChzdXJmYWNlX3ZhcmlhYmxlcykpKQpzdXJmYWNlX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX25ldXNbLCB2YXJpYWJsZTo9YXMuZmFjdG9yKFYxKV1bLCBjb2VmOj1hcy5udW1lcmljKFYxKV1bLCBwX3ZhbHVlOj1hcy5udW1lcmljKFYxKV1bLCBBSUNjOj1hcy5udW1lcmljKFYxKV0Kc3VyZmFjZV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9uZXVzWywgVjEgOj0gTlVMTF0KICAKICBmb3IgKGkgaW4gMTpsZW5ndGgoc3VyZmFjZV92YXJpYWJsZXMpKXsKICAgIG1vZCA8LSBnbG1lcihjb2wgfiBnZXQoc3VyZmFjZV92YXJpYWJsZXNbaV0pICsgKDF8eWVhcl9mYWN0b3IpLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IHNwcF9tYXN0ZXJfenRlbXBbcmVnID09ICJuZXVzIl0pCiAgICBzdXJmYWNlX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX25ldXNbaSx2YXJpYWJsZSA6PSBzdXJmYWNlX3ZhcmlhYmxlc1tpXV0KICAgIHN1cmZhY2VfY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fbmV1c1tpLGNvZWYgOj0gY29lZihzdW1tYXJ5KG1vZCkpWywiRXN0aW1hdGUiXVsyXV0KICAgIHN1cmZhY2VfY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fbmV1c1tpLHBfdmFsdWUgOj0gY29lZihzdW1tYXJ5KG1vZCkpWywiUHIoPnx6fCkiXVsyXV0KICAgIHN1cmZhY2VfY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fbmV1c1tpLEFJQ2MgOj0gQUlDYyhtb2QpXQogICAgCiAgICBwcmludChwYXN0ZShpLCBsZW5ndGgoc3VyZmFjZV92YXJpYWJsZXMpLCBzZXAgPSAiLyIpKQogICAgICAKICB9CiNhZGQgY29sdW1uIGZvciB0aG9zZSB0aGF0IGRpZG4ndCBjb252ZXJnZQpzdXJmYWNlX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX25ldXMkY29udmVyZ2UgPC0gVApzdXJmYWNlX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX25ldXMkY29udmVyZ2VbYygxLCA2OjgsIDEyLCAxNSwgMTcsIDIxLCAyMywgMjIsIDM2OjQwKV0gPC0gRgoKI2FkZCBjb2x1bW4gdG8gZGVzaWduYXRlIHJlZ2lvbiAKICBzdXJmYWNlX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX25ldXMkcmVnIDwtICJuZXVzIgoKI25ld2YgKDExMiBmYWlsZWQgdG8gY29udmVyZ2UpCgpzdXJmYWNlX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX25ld2YgPC0gYXMuZGF0YS50YWJsZShtYXRyaXgobnJvdyA9IGxlbmd0aChzdXJmYWNlX3ZhcmlhYmxlcykpKQpzdXJmYWNlX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX25ld2ZbLCB2YXJpYWJsZTo9YXMuZmFjdG9yKFYxKV1bLCBjb2VmOj1hcy5udW1lcmljKFYxKV1bLCBwX3ZhbHVlOj1hcy5udW1lcmljKFYxKV1bLCBBSUNjOj1hcy5udW1lcmljKFYxKV0Kc3VyZmFjZV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9uZXdmWywgVjEgOj0gTlVMTF0KICAKICBmb3IgKGkgaW4gMTpsZW5ndGgoc3VyZmFjZV92YXJpYWJsZXMpKXsKICAgIG1vZCA8LSBnbG1lcihjb2wgfiBnZXQoc3VyZmFjZV92YXJpYWJsZXNbaV0pICsgKDF8eWVhcl9mYWN0b3IpLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IHNwcF9tYXN0ZXJfenRlbXBbcmVnID09ICJuZXdmIl0pCiAgICBzdXJmYWNlX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX25ld2ZbaSx2YXJpYWJsZSA6PSBzdXJmYWNlX3ZhcmlhYmxlc1tpXV0KICAgIHN1cmZhY2VfY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fbmV3ZltpLGNvZWYgOj0gY29lZihzdW1tYXJ5KG1vZCkpWywiRXN0aW1hdGUiXVsyXV0KICAgIHN1cmZhY2VfY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fbmV3ZltpLHBfdmFsdWUgOj0gY29lZihzdW1tYXJ5KG1vZCkpWywiUHIoPnx6fCkiXVsyXV0KICAgIHN1cmZhY2VfY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fbmV3ZltpLEFJQ2MgOj0gQUlDYyhtb2QpXQogICAgCiAgICBwcmludChwYXN0ZShpLCBsZW5ndGgoc3VyZmFjZV92YXJpYWJsZXMpLCBzZXAgPSAiLyIpKQogICAgICAKICB9CgojYWRkIGNvbHVtbiBmb3IgdGhvc2UgdGhhdCBkaWRuJ3QgY29udmVyZ2UKc3VyZmFjZV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9uZXdmJGNvbnZlcmdlIDwtIFQKc3VyZmFjZV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9uZXdmJGNvbnZlcmdlW2MoMTEyKV0gPC0gRgoKI2FkZCBjb2x1bW4gdG8gZGVzaWduYXRlIHJlZ2lvbiAKICBzdXJmYWNlX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX25ld2YkcmVnIDwtICJuZXdmIgoKCiNzaGVsZiAoMzc6MzkgZGlkbid0IGNvbnZlcmdlKQoKc3VyZmFjZV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9zaGVsZiA8LSBhcy5kYXRhLnRhYmxlKG1hdHJpeChucm93ID0gbGVuZ3RoKHN1cmZhY2VfdmFyaWFibGVzKSkpCnN1cmZhY2VfY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fc2hlbGZbLCB2YXJpYWJsZTo9YXMuZmFjdG9yKFYxKV1bLCBjb2VmOj1hcy5udW1lcmljKFYxKV1bLCBwX3ZhbHVlOj1hcy5udW1lcmljKFYxKV1bLCBBSUNjOj1hcy5udW1lcmljKFYxKV0Kc3VyZmFjZV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9zaGVsZlssIFYxIDo9IE5VTExdCiAgCiAgZm9yIChpIGluIDE6bGVuZ3RoKHN1cmZhY2VfdmFyaWFibGVzKSl7CiAgICBtb2QgPC0gZ2xtZXIoY29sIH4gZ2V0KHN1cmZhY2VfdmFyaWFibGVzW2ldKSArICgxfHllYXJfZmFjdG9yKSwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBzcHBfbWFzdGVyX3p0ZW1wW3JlZyA9PSAic2hlbGYiXSkKICAgIHN1cmZhY2VfY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fc2hlbGZbaSx2YXJpYWJsZSA6PSBzdXJmYWNlX3ZhcmlhYmxlc1tpXV0KICAgIHN1cmZhY2VfY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fc2hlbGZbaSxjb2VmIDo9IGNvZWYoc3VtbWFyeShtb2QpKVssIkVzdGltYXRlIl1bMl1dCiAgICBzdXJmYWNlX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX3NoZWxmW2kscF92YWx1ZSA6PSBjb2VmKHN1bW1hcnkobW9kKSlbLCJQcig+fHp8KSJdWzJdXQogICAgc3VyZmFjZV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9zaGVsZltpLEFJQ2MgOj0gQUlDYyhtb2QpXQogICAgCiAgICBwcmludChwYXN0ZShpLCBsZW5ndGgoc3VyZmFjZV92YXJpYWJsZXMpLCBzZXAgPSAiLyIpKQogICAgICAKICB9CgojYWRkIGNvbHVtbiBmb3IgdGhvc2UgdGhhdCBkaWRuJ3QgY29udmVyZ2UKc3VyZmFjZV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9zaGVsZiRjb252ZXJnZSA8LSBUCnN1cmZhY2VfY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fc2hlbGYkY29udmVyZ2VbYygzNzozOSldIDwtIEYKCiNhZGQgY29sdW1uIHRvIGRlc2lnbmF0ZSByZWdpb24gCiAgc3VyZmFjZV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9zaGVsZiRyZWcgPC0gInNoZWxmIgoKCiNzYSAoYWxsIGFyZSBzaW5ndWxhcml0aWVzPz8pCgpzdXJmYWNlX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX3NhIDwtIGFzLmRhdGEudGFibGUobWF0cml4KG5yb3cgPSBsZW5ndGgoc3VyZmFjZV92YXJpYWJsZXMpKSkKc3VyZmFjZV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9zYVssIHZhcmlhYmxlOj1hcy5mYWN0b3IoVjEpXVssIGNvZWY6PWFzLm51bWVyaWMoVjEpXVssIHBfdmFsdWU6PWFzLm51bWVyaWMoVjEpXVssIEFJQ2M6PWFzLm51bWVyaWMoVjEpXQpzdXJmYWNlX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX3NhWywgVjEgOj0gTlVMTF0KICAKICBmb3IgKGkgaW4gMTpsZW5ndGgoc3VyZmFjZV92YXJpYWJsZXMpKXsKICAgIG1vZCA8LSBnbG1lcihjb2wgfiBnZXQoc3VyZmFjZV92YXJpYWJsZXNbaV0pICsgKDF8eWVhcl9mYWN0b3IpLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IHNwcF9tYXN0ZXJfenRlbXBbcmVnID09ICJzYSJdKQogICAgc3VyZmFjZV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9zYVtpLHZhcmlhYmxlIDo9IHN1cmZhY2VfdmFyaWFibGVzW2ldXQogICAgc3VyZmFjZV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9zYVtpLGNvZWYgOj0gY29lZihzdW1tYXJ5KG1vZCkpWywiRXN0aW1hdGUiXVsyXV0KICAgIHN1cmZhY2VfY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fc2FbaSxwX3ZhbHVlIDo9IGNvZWYoc3VtbWFyeShtb2QpKVssIlByKD58enwpIl1bMl1dCiAgICBzdXJmYWNlX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX3NhW2ksQUlDYyA6PSBBSUNjKG1vZCldCiAgICAKICAgIHByaW50KHBhc3RlKGksIGxlbmd0aChzdXJmYWNlX3ZhcmlhYmxlcyksIHNlcCA9ICIvIikpCiAgICAgIAogIH0KCiNhZGQgY29sdW1uIGZvciB0aG9zZSB0aGF0IGRpZG4ndCBjb252ZXJnZQpzdXJmYWNlX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX3NhJGNvbnZlcmdlIDwtIFQKc3VyZmFjZV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9zYSRjb252ZXJnZVtjKDE6MTI0KV0gPC0gRgoKI2FkZCBjb2x1bW4gdG8gZGVzaWduYXRlIHJlZ2lvbiAKICBzdXJmYWNlX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX3NhJHJlZyA8LSAic2EiCgoKI3djdHJpICgxNiwgMjcsIDM3LCAzOCwgNTEsIDUyLCA2MCwgNjEsIDY0LCA2NSwgNjgsIDcwLCA3NCwgNzUsIDk3LCA5OSwgMTAyLCAxMDQsIDExMiBmYWlsZWQgdG8gY29udmVyZ2UpCgpzdXJmYWNlX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX3djdHJpIDwtIGFzLmRhdGEudGFibGUobWF0cml4KG5yb3cgPSBsZW5ndGgoc3VyZmFjZV92YXJpYWJsZXMpKSkKc3VyZmFjZV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl93Y3RyaVssIHZhcmlhYmxlOj1hcy5mYWN0b3IoVjEpXVssIGNvZWY6PWFzLm51bWVyaWMoVjEpXVssIHBfdmFsdWU6PWFzLm51bWVyaWMoVjEpXVssIEFJQ2M6PWFzLm51bWVyaWMoVjEpXQpzdXJmYWNlX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX3djdHJpWywgVjEgOj0gTlVMTF0KICAKICBmb3IgKGkgaW4gMTpsZW5ndGgoc3VyZmFjZV92YXJpYWJsZXMpKXsKICAgIG1vZCA8LSBnbG1lcihjb2wgfiBnZXQoc3VyZmFjZV92YXJpYWJsZXNbaV0pICsgKDF8eWVhcl9mYWN0b3IpLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IHNwcF9tYXN0ZXJfenRlbXBbcmVnID09ICJ3Y3RyaSJdKQogICAgc3VyZmFjZV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl93Y3RyaVtpLHZhcmlhYmxlIDo9IHN1cmZhY2VfdmFyaWFibGVzW2ldXQogICAgc3VyZmFjZV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl93Y3RyaVtpLGNvZWYgOj0gY29lZihzdW1tYXJ5KG1vZCkpWywiRXN0aW1hdGUiXVsyXV0KICAgIHN1cmZhY2VfY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fd2N0cmlbaSxwX3ZhbHVlIDo9IGNvZWYoc3VtbWFyeShtb2QpKVssIlByKD58enwpIl1bMl1dCiAgICBzdXJmYWNlX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX3djdHJpW2ksQUlDYyA6PSBBSUNjKG1vZCldCiAgICAKICAgIHByaW50KHBhc3RlKGksIGxlbmd0aChzdXJmYWNlX3ZhcmlhYmxlcyksIHNlcCA9ICIvIikpCiAgICAgIAogIH0KCiNhZGQgY29sdW1uIGZvciB0aG9zZSB0aGF0IGRpZG4ndCBjb252ZXJnZQpzdXJmYWNlX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX3djdHJpJGNvbnZlcmdlIDwtIFQKc3VyZmFjZV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl93Y3RyaSRjb252ZXJnZVtjKDE2LCAyNywgMzcsIDM4LCA1MSwgNTIsIDYwLCA2MSwgNjQsIDY1LCA2OCwgNzAsIDc0LCA3NSwgOTcsIDk5LCAxMDIsIDEwNCwgMTEyKV0gPC0gRgoKI2FkZCBjb2x1bW4gdG8gZGVzaWduYXRlIHJlZ2lvbiAKICBzdXJmYWNlX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX3djdHJpJHJlZyA8LSAid2N0cmkiCmBgYAoKTm93LCBJJ2xsIG1lcmdlIGFsbCBzdXJmYWNlIGNvbG9uaXphdGlvbiBtb2RlbHMKYGBge3IgbWVyZ2Ugc3VyZmFjZSBjb2xvbml6YXRpb24gbW9kZWxzfQpzdXJmYWNlX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX2J5cmVnaW9uIDwtIHJiaW5kKHN1cmZhY2VfY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fYWksIHN1cmZhY2VfY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fZWJzLCBzdXJmYWNlX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX2dtZXgsIHN1cmZhY2VfY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fZ29hLCBzdXJmYWNlX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX25ldXMsIHN1cmZhY2VfY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fbmV3Ziwgc3VyZmFjZV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9zYSwgc3VyZmFjZV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9zaGVsZiwgc3VyZmFjZV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl93Y3RyaSkKYGBgCgpCZXN0IHN1cmZhY2UgY29sb25pemF0aW9uIG1vZGVscyBwZXIgcmVnaW9uCgpgYGB7ciBiZXN0IHN1cmZhY2UgY29sb25pemF0aW9uIG1vZGVscyBwZXIgcmVnaW9ufQpzdXJmYWNlX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX2J5cmVnaW9uICU+JQogIGZpbHRlcihjb252ZXJnZSA9PSBUUlVFLCAhZ3JlcGwoIm1lYW4iLCB2YXJpYWJsZSkpICU+JSAjaWdub3JpbmcgbWVhbiBmb3Igbm93LCBhbmQgZ2V0IHJpZCBvZiB0aG9zZSB0aGF0IGRpZG4ndCBjb252ZXJnZQogIGdyb3VwX2J5KHJlZykgJT4lICNncm91cCBieSByZWdpb24KICBhcnJhbmdlKEFJQ2MpICU+JSAjYXJyYW5nZSBieSBBSUNjCiAgdG9wX24oLTUsIEFJQ2MpICN0YWtlIDUgYmVzdCBtb2RlbHMgKGxvd2VzdCBBSUNjKQogIApgYGAKCioqKioqKioKI0JvdHRvbSBjb2xvbml6YXRpb24gY29tcGFyaXNvbiBieSByZWdpb24KYGBge3IgYm90dG9tIGNvbG9uaXphdGlvbiBjb21wYXJpc29uIGJ5IHJlZ2lvbn0KYm90dG9tX3ZhcmlhYmxlcyA8LSBjb2xuYW1lcyhzcHBfbWFzdGVyX3p0ZW1wWywxNjk6MjkyXSkKICAKI3JlZ2lvbnMKCiNhaSAoMTAxLCAxMTAgZmFpbCB0byBjb252ZXJnZSkKYm90dG9tX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX2FpIDwtIGFzLmRhdGEudGFibGUobWF0cml4KG5yb3cgPSBsZW5ndGgoYm90dG9tX3ZhcmlhYmxlcykpKQpib3R0b21fY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fYWlbLCB2YXJpYWJsZTo9YXMuZmFjdG9yKFYxKV1bLCBjb2VmOj1hcy5udW1lcmljKFYxKV1bLCBwX3ZhbHVlOj1hcy5udW1lcmljKFYxKV1bLCBBSUNjOj1hcy5udW1lcmljKFYxKV0KYm90dG9tX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX2FpWywgVjEgOj0gTlVMTF0KICAKICBmb3IgKGkgaW4gMTpsZW5ndGgoYm90dG9tX3ZhcmlhYmxlcykpewogICAgbW9kIDwtIGdsbWVyKGNvbCB+IGdldChib3R0b21fdmFyaWFibGVzW2ldKSArICgxfHllYXJfZmFjdG9yKSwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBzcHBfbWFzdGVyX3p0ZW1wW3JlZyA9PSAiYWkiXSkKICAgIGJvdHRvbV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9haVtpLHZhcmlhYmxlIDo9IGJvdHRvbV92YXJpYWJsZXNbaV1dCiAgICBib3R0b21fY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fYWlbaSxjb2VmIDo9IGNvZWYoc3VtbWFyeShtb2QpKVssIkVzdGltYXRlIl1bMl1dCiAgICBib3R0b21fY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fYWlbaSxwX3ZhbHVlIDo9IGNvZWYoc3VtbWFyeShtb2QpKVssIlByKD58enwpIl1bMl1dCiAgICBib3R0b21fY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fYWlbaSxBSUNjIDo9IEFJQ2MobW9kKV0KICAgIAogICAgcHJpbnQocGFzdGUoaSwgbGVuZ3RoKGJvdHRvbV92YXJpYWJsZXMpLCBzZXAgPSAiLyIpKQogICAgICAKICB9CiAgI2FkZCBjb2x1bW4gZm9yIHRob3NlIHRoYXQgZGlkbid0IGNvbnZlcmdlCiAgYm90dG9tX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX2FpJGNvbnZlcmdlIDwtIFQKICBib3R0b21fY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fYWkkY29udmVyZ2VbYygxMDEsIDExMCldIDwtIEYKICAKICAjYWRkIGNvbHVtbiB0byBkZXNpZ25hdGUgcmVnaW9uIAogIGJvdHRvbV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9haSRyZWcgPC0gImFpIgogIAojZWJzICgxMCBkaWQgbm90IGNvbnZlcmdlKQoKYm90dG9tX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX2VicyA8LSBhcy5kYXRhLnRhYmxlKG1hdHJpeChucm93ID0gbGVuZ3RoKGJvdHRvbV92YXJpYWJsZXMpKSkKYm90dG9tX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX2Vic1ssIHZhcmlhYmxlOj1hcy5mYWN0b3IoVjEpXVssIGNvZWY6PWFzLm51bWVyaWMoVjEpXVssIHBfdmFsdWU6PWFzLm51bWVyaWMoVjEpXVssIEFJQ2M6PWFzLm51bWVyaWMoVjEpXQpib3R0b21fY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fZWJzWywgVjEgOj0gTlVMTF0KICAKICBmb3IgKGkgaW4gMTpsZW5ndGgoYm90dG9tX3ZhcmlhYmxlcykpewogICAgbW9kIDwtIGdsbWVyKGNvbCB+IGdldChib3R0b21fdmFyaWFibGVzW2ldKSArICgxfHllYXJfZmFjdG9yKSwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBzcHBfbWFzdGVyX3p0ZW1wW3JlZyA9PSAiZWJzIl0pCiAgICBib3R0b21fY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fZWJzW2ksdmFyaWFibGUgOj0gYm90dG9tX3ZhcmlhYmxlc1tpXV0KICAgIGJvdHRvbV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9lYnNbaSxjb2VmIDo9IGNvZWYoc3VtbWFyeShtb2QpKVssIkVzdGltYXRlIl1bMl1dCiAgICBib3R0b21fY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fZWJzW2kscF92YWx1ZSA6PSBjb2VmKHN1bW1hcnkobW9kKSlbLCJQcig+fHp8KSJdWzJdXQogICAgYm90dG9tX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX2Vic1tpLEFJQ2MgOj0gQUlDYyhtb2QpXQogICAgCiAgICBwcmludChwYXN0ZShpLCBsZW5ndGgoYm90dG9tX3ZhcmlhYmxlcyksIHNlcCA9ICIvIikpCiAgICAgIAogIH0KICAjYWRkIGNvbHVtbiBmb3IgdGhvc2UgdGhhdCBkaWRuJ3QgY29udmVyZ2UKICBib3R0b21fY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fZWJzJGNvbnZlcmdlIDwtIFQKICBib3R0b21fY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fZWJzJGNvbnZlcmdlW2MoMTApXSA8LSBGCiAgCiAgI2FkZCBjb2x1bW4gdG8gZGVzaWduYXRlIHJlZ2lvbiAKICBib3R0b21fY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fZWJzJHJlZyA8LSAiZWJzIgogIAojZ21leCAoMSwgNiwgMTAsIDEzLCAxNSwgMTgsIDE5LCAyMCwgMjMsIDI0LCAyNSwgMjYsIDI4LCAyOSwgMzAsIDMxIGZhaWwgdG8gY29udmVyZ2UpCgpib3R0b21fY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fZ21leCA8LSBhcy5kYXRhLnRhYmxlKG1hdHJpeChucm93ID0gbGVuZ3RoKGJvdHRvbV92YXJpYWJsZXMpKSkKYm90dG9tX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX2dtZXhbLCB2YXJpYWJsZTo9YXMuZmFjdG9yKFYxKV1bLCBjb2VmOj1hcy5udW1lcmljKFYxKV1bLCBwX3ZhbHVlOj1hcy5udW1lcmljKFYxKV1bLCBBSUNjOj1hcy5udW1lcmljKFYxKV0KYm90dG9tX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX2dtZXhbLCBWMSA6PSBOVUxMXQogIAogIGZvciAoaSBpbiAxOmxlbmd0aChib3R0b21fdmFyaWFibGVzKSl7CiAgICBtb2QgPC0gZ2xtZXIoY29sIH4gZ2V0KGJvdHRvbV92YXJpYWJsZXNbaV0pICsgKDF8eWVhcl9mYWN0b3IpLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IHNwcF9tYXN0ZXJfenRlbXBbcmVnID09ICJnbWV4Il0pCiAgICBtb2QxIDwtIGdsbWVyKGNvbCB+IGdldChib3R0b21fdmFyaWFibGVzW2ldKSArICgxfHllYXJfZmFjdG9yKSwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBzcHBfbWFzdGVyX3p0ZW1wW3JlZyA9PSAiZ21leCJdKQogICAgYm90dG9tX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX2dtZXhbaSx2YXJpYWJsZSA6PSBib3R0b21fdmFyaWFibGVzW2ldXQogICAgYm90dG9tX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX2dtZXhbaSxjb2VmIDo9IGNvZWYoc3VtbWFyeShtb2QpKVssIkVzdGltYXRlIl1bMl1dCiAgICBib3R0b21fY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fZ21leFtpLHBfdmFsdWUgOj0gY29lZihzdW1tYXJ5KG1vZCkpWywiUHIoPnx6fCkiXVsyXV0KICAgIGJvdHRvbV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9nbWV4W2ksQUlDYyA6PSBBSUNjKG1vZCldCiAgICAKICAgIHByaW50KHBhc3RlKGksIGxlbmd0aChib3R0b21fdmFyaWFibGVzKSwgc2VwID0gIi8iKSkKICAgICAgCiAgfQogICNhZGQgY29sdW1uIGZvciB0aG9zZSB0aGF0IGRpZG4ndCBjb252ZXJnZQogIGJvdHRvbV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9nbWV4JGNvbnZlcmdlIDwtIFQKICBib3R0b21fY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fZ21leCRjb252ZXJnZVtjKDEsIDYsIDEwLCAxMywgMTUsIDE4LCAxOSwgMjAsIDIzLCAyNCwgMjUsIDI2LCAyOCwgMjksIDMwLCAzMSldIDwtIEYKICAKICAjYWRkIGNvbHVtbiB0byBkZXNpZ25hdGUgcmVnaW9uIAogIGJvdHRvbV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9nbWV4JHJlZyA8LSAiZ21leCIKCiNnb2EgKGFsbCBjb252ZXJnZSkKCmJvdHRvbV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9nb2EgPC0gYXMuZGF0YS50YWJsZShtYXRyaXgobnJvdyA9IGxlbmd0aChib3R0b21fdmFyaWFibGVzKSkpCmJvdHRvbV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9nb2FbLCB2YXJpYWJsZTo9YXMuZmFjdG9yKFYxKV1bLCBjb2VmOj1hcy5udW1lcmljKFYxKV1bLCBwX3ZhbHVlOj1hcy5udW1lcmljKFYxKV1bLCBBSUNjOj1hcy5udW1lcmljKFYxKV0KYm90dG9tX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX2dvYVssIFYxIDo9IE5VTExdCiAgCiAgZm9yIChpIGluIDE6bGVuZ3RoKGJvdHRvbV92YXJpYWJsZXMpKXsKICAgIG1vZCA8LSBnbG1lcihjb2wgfiBnZXQoYm90dG9tX3ZhcmlhYmxlc1tpXSkgKyAoMXx5ZWFyX2ZhY3RvciksIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gc3BwX21hc3Rlcl96dGVtcFtyZWcgPT0gImdvYSJdKQogICAgYm90dG9tX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX2dvYVtpLHZhcmlhYmxlIDo9IGJvdHRvbV92YXJpYWJsZXNbaV1dCiAgICBib3R0b21fY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fZ29hW2ksY29lZiA6PSBjb2VmKHN1bW1hcnkobW9kKSlbLCJFc3RpbWF0ZSJdWzJdXQogICAgYm90dG9tX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX2dvYVtpLHBfdmFsdWUgOj0gY29lZihzdW1tYXJ5KG1vZCkpWywiUHIoPnx6fCkiXVsyXV0KICAgIGJvdHRvbV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9nb2FbaSxBSUNjIDo9IEFJQ2MobW9kKV0KICAgIAogICAgcHJpbnQocGFzdGUoaSwgbGVuZ3RoKGJvdHRvbV92YXJpYWJsZXMpLCBzZXAgPSAiLyIpKQogICAgICAKICB9CiAgI2FkZCBjb2x1bW4gZm9yIHRob3NlIHRoYXQgZGlkbid0IGNvbnZlcmdlCiAgYm90dG9tX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX2dvYSRjb252ZXJnZSA8LSBUCiAgCiAgI2FkZCBjb2x1bW4gdG8gZGVzaWduYXRlIHJlZ2lvbiAKICBib3R0b21fY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fZ29hJHJlZyA8LSAiZ29hIgoKI25ldXMgKDMsIDQsIDcsIDgsIDEwLCAxMiwgMTMsIDE4LCAyMSwgMjMsIDI5LCAzMCwgMzEsIDM4LCAzOSwgNDAgZmFpbGVkIHRvIGNvbnZlcmdlKQoKYm90dG9tX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX25ldXMgPC0gYXMuZGF0YS50YWJsZShtYXRyaXgobnJvdyA9IGxlbmd0aChib3R0b21fdmFyaWFibGVzKSkpCmJvdHRvbV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9uZXVzWywgdmFyaWFibGU6PWFzLmZhY3RvcihWMSldWywgY29lZjo9YXMubnVtZXJpYyhWMSldWywgcF92YWx1ZTo9YXMubnVtZXJpYyhWMSldWywgQUlDYzo9YXMubnVtZXJpYyhWMSldCmJvdHRvbV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9uZXVzWywgVjEgOj0gTlVMTF0KICAKICBmb3IgKGkgaW4gMTpsZW5ndGgoYm90dG9tX3ZhcmlhYmxlcykpewogICAgbW9kIDwtIGdsbWVyKGNvbCB+IGdldChib3R0b21fdmFyaWFibGVzW2ldKSArICgxfHllYXJfZmFjdG9yKSwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBzcHBfbWFzdGVyX3p0ZW1wW3JlZyA9PSAibmV1cyJdKQogICAgYm90dG9tX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX25ldXNbaSx2YXJpYWJsZSA6PSBib3R0b21fdmFyaWFibGVzW2ldXQogICAgYm90dG9tX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX25ldXNbaSxjb2VmIDo9IGNvZWYoc3VtbWFyeShtb2QpKVssIkVzdGltYXRlIl1bMl1dCiAgICBib3R0b21fY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fbmV1c1tpLHBfdmFsdWUgOj0gY29lZihzdW1tYXJ5KG1vZCkpWywiUHIoPnx6fCkiXVsyXV0KICAgIGJvdHRvbV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9uZXVzW2ksQUlDYyA6PSBBSUNjKG1vZCldCiAgICAKICAgIHByaW50KHBhc3RlKGksIGxlbmd0aChib3R0b21fdmFyaWFibGVzKSwgc2VwID0gIi8iKSkKICAgICAgCiAgfQojYWRkIGNvbHVtbiBmb3IgdGhvc2UgdGhhdCBkaWRuJ3QgY29udmVyZ2UKYm90dG9tX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX25ldXMkY29udmVyZ2UgPC0gVApib3R0b21fY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fbmV1cyRjb252ZXJnZVtjKDMsIDQsIDcsIDgsIDEwLCAxMiwgMTMsIDE4LCAyMSwgMjMsIDI5LCAzMCwgMzEsIDM4LCAzOSwgNDApXSA8LSBGCgojYWRkIGNvbHVtbiB0byBkZXNpZ25hdGUgcmVnaW9uIAogIGJvdHRvbV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9uZXVzJHJlZyA8LSAibmV1cyIKCiNuZXdmICgxMCwgMjAsIDQwLCA1MywgNTQsIDYyLCA2MywgNzEsIDgwLCA4MSwgODgsIDk3LCAgZmFpbGVkIHRvIGNvbnZlcmdlKQoKYm90dG9tX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX25ld2YgPC0gYXMuZGF0YS50YWJsZShtYXRyaXgobnJvdyA9IGxlbmd0aChib3R0b21fdmFyaWFibGVzKSkpCmJvdHRvbV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9uZXdmWywgdmFyaWFibGU6PWFzLmZhY3RvcihWMSldWywgY29lZjo9YXMubnVtZXJpYyhWMSldWywgcF92YWx1ZTo9YXMubnVtZXJpYyhWMSldWywgQUlDYzo9YXMubnVtZXJpYyhWMSldCmJvdHRvbV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9uZXdmWywgVjEgOj0gTlVMTF0KICAKICBmb3IgKGkgaW4gMTpsZW5ndGgoYm90dG9tX3ZhcmlhYmxlcykpewogICAgbW9kIDwtIGdsbWVyKGNvbCB+IGdldChib3R0b21fdmFyaWFibGVzW2ldKSArICgxfHllYXJfZmFjdG9yKSwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBzcHBfbWFzdGVyX3p0ZW1wW3JlZyA9PSAibmV3ZiJdKQogICAgYm90dG9tX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX25ld2ZbaSx2YXJpYWJsZSA6PSBib3R0b21fdmFyaWFibGVzW2ldXQogICAgYm90dG9tX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX25ld2ZbaSxjb2VmIDo9IGNvZWYoc3VtbWFyeShtb2QpKVssIkVzdGltYXRlIl1bMl1dCiAgICBib3R0b21fY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fbmV3ZltpLHBfdmFsdWUgOj0gY29lZihzdW1tYXJ5KG1vZCkpWywiUHIoPnx6fCkiXVsyXV0KICAgIGJvdHRvbV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9uZXdmW2ksQUlDYyA6PSBBSUNjKG1vZCldCiAgICAKICAgIHByaW50KHBhc3RlKGksIGxlbmd0aChib3R0b21fdmFyaWFibGVzKSwgc2VwID0gIi8iKSkKICAgICAgCiAgfQoKI2FkZCBjb2x1bW4gZm9yIHRob3NlIHRoYXQgZGlkbid0IGNvbnZlcmdlCmJvdHRvbV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9uZXdmJGNvbnZlcmdlIDwtIFQKYm90dG9tX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX25ld2YkY29udmVyZ2VbYygxMCwgMjAsIDQwLCA1MywgNTQsIDYyLCA2MywgNzEsIDgwLCA4MSwgODgsIDk3KV0gPC0gRgoKI2FkZCBjb2x1bW4gdG8gZGVzaWduYXRlIHJlZ2lvbiAKICBib3R0b21fY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fbmV3ZiRyZWcgPC0gIm5ld2YiCgoKI3NoZWxmIChub25lIGRpZG4ndCBjb252ZXJnZSkKCmJvdHRvbV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9zaGVsZiA8LSBhcy5kYXRhLnRhYmxlKG1hdHJpeChucm93ID0gbGVuZ3RoKGJvdHRvbV92YXJpYWJsZXMpKSkKYm90dG9tX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX3NoZWxmWywgdmFyaWFibGU6PWFzLmZhY3RvcihWMSldWywgY29lZjo9YXMubnVtZXJpYyhWMSldWywgcF92YWx1ZTo9YXMubnVtZXJpYyhWMSldWywgQUlDYzo9YXMubnVtZXJpYyhWMSldCmJvdHRvbV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9zaGVsZlssIFYxIDo9IE5VTExdCiAgCiAgZm9yIChpIGluIDE6bGVuZ3RoKGJvdHRvbV92YXJpYWJsZXMpKXsKICAgIG1vZCA8LSBnbG1lcihjb2wgfiBnZXQoYm90dG9tX3ZhcmlhYmxlc1tpXSkgKyAoMXx5ZWFyX2ZhY3RvciksIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gc3BwX21hc3Rlcl96dGVtcFtyZWcgPT0gInNoZWxmIl0pCiAgICBib3R0b21fY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fc2hlbGZbaSx2YXJpYWJsZSA6PSBib3R0b21fdmFyaWFibGVzW2ldXQogICAgYm90dG9tX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX3NoZWxmW2ksY29lZiA6PSBjb2VmKHN1bW1hcnkobW9kKSlbLCJFc3RpbWF0ZSJdWzJdXQogICAgYm90dG9tX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX3NoZWxmW2kscF92YWx1ZSA6PSBjb2VmKHN1bW1hcnkobW9kKSlbLCJQcig+fHp8KSJdWzJdXQogICAgYm90dG9tX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX3NoZWxmW2ksQUlDYyA6PSBBSUNjKG1vZCldCiAgICAKICAgIHByaW50KHBhc3RlKGksIGxlbmd0aChib3R0b21fdmFyaWFibGVzKSwgc2VwID0gIi8iKSkKICAgICAgCiAgfQoKI2FkZCBjb2x1bW4gZm9yIHRob3NlIHRoYXQgZGlkbid0IGNvbnZlcmdlCmJvdHRvbV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9zaGVsZiRjb252ZXJnZSA8LSBUCgojYWRkIGNvbHVtbiB0byBkZXNpZ25hdGUgcmVnaW9uIAogIGJvdHRvbV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9zaGVsZiRyZWcgPC0gInNoZWxmIgoKCiNzYSAoYWxsIGFyZSBzaW5ndWxhcml0aWVzPz8pCgpib3R0b21fY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fc2EgPC0gYXMuZGF0YS50YWJsZShtYXRyaXgobnJvdyA9IGxlbmd0aChib3R0b21fdmFyaWFibGVzKSkpCmJvdHRvbV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9zYVssIHZhcmlhYmxlOj1hcy5mYWN0b3IoVjEpXVssIGNvZWY6PWFzLm51bWVyaWMoVjEpXVssIHBfdmFsdWU6PWFzLm51bWVyaWMoVjEpXVssIEFJQ2M6PWFzLm51bWVyaWMoVjEpXQpib3R0b21fY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fc2FbLCBWMSA6PSBOVUxMXQogIAogIGZvciAoaSBpbiAxOmxlbmd0aChib3R0b21fdmFyaWFibGVzKSl7CiAgICBtb2QgPC0gZ2xtZXIoY29sIH4gZ2V0KGJvdHRvbV92YXJpYWJsZXNbaV0pICsgKDF8eWVhcl9mYWN0b3IpLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IHNwcF9tYXN0ZXJfenRlbXBbcmVnID09ICJzYSJdKQogICAgYm90dG9tX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX3NhW2ksdmFyaWFibGUgOj0gYm90dG9tX3ZhcmlhYmxlc1tpXV0KICAgIGJvdHRvbV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9zYVtpLGNvZWYgOj0gY29lZihzdW1tYXJ5KG1vZCkpWywiRXN0aW1hdGUiXVsyXV0KICAgIGJvdHRvbV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9zYVtpLHBfdmFsdWUgOj0gY29lZihzdW1tYXJ5KG1vZCkpWywiUHIoPnx6fCkiXVsyXV0KICAgIGJvdHRvbV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9zYVtpLEFJQ2MgOj0gQUlDYyhtb2QpXQogICAgCiAgICBwcmludChwYXN0ZShpLCBsZW5ndGgoYm90dG9tX3ZhcmlhYmxlcyksIHNlcCA9ICIvIikpCiAgICAgIAogIH0KCiNhZGQgY29sdW1uIGZvciB0aG9zZSB0aGF0IGRpZG4ndCBjb252ZXJnZQpib3R0b21fY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fc2EkY29udmVyZ2UgPC0gVApib3R0b21fY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fc2EkY29udmVyZ2VbYygxOjEyNCldIDwtIEYKCiNhZGQgY29sdW1uIHRvIGRlc2lnbmF0ZSByZWdpb24gCiAgYm90dG9tX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX3NhJHJlZyA8LSAic2EiCgoKI3djdHJpICgxNCwgMjMsIDMzLCA0OSwgNTEsIDUyLCA1NiwgNTgsIDYwLCA2NSwgNzYsIDc4LCA4OSwgOTMsIDk4LCAxMDQsIDEwOSwgMTEyLCAxMTMsIDExNSwgMTE5IGZhaWxlZCB0byBjb252ZXJnZSkKCmJvdHRvbV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl93Y3RyaSA8LSBhcy5kYXRhLnRhYmxlKG1hdHJpeChucm93ID0gbGVuZ3RoKGJvdHRvbV92YXJpYWJsZXMpKSkKYm90dG9tX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX3djdHJpWywgdmFyaWFibGU6PWFzLmZhY3RvcihWMSldWywgY29lZjo9YXMubnVtZXJpYyhWMSldWywgcF92YWx1ZTo9YXMubnVtZXJpYyhWMSldWywgQUlDYzo9YXMubnVtZXJpYyhWMSldCmJvdHRvbV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl93Y3RyaVssIFYxIDo9IE5VTExdCiAgCiAgZm9yIChpIGluIDE6bGVuZ3RoKGJvdHRvbV92YXJpYWJsZXMpKXsKICAgIG1vZCA8LSBnbG1lcihjb2wgfiBnZXQoYm90dG9tX3ZhcmlhYmxlc1tpXSkgKyAoMXx5ZWFyX2ZhY3RvciksIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gc3BwX21hc3Rlcl96dGVtcFtyZWcgPT0gIndjdHJpIl0pCiAgICBib3R0b21fY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fd2N0cmlbaSx2YXJpYWJsZSA6PSBib3R0b21fdmFyaWFibGVzW2ldXQogICAgYm90dG9tX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX3djdHJpW2ksY29lZiA6PSBjb2VmKHN1bW1hcnkobW9kKSlbLCJFc3RpbWF0ZSJdWzJdXQogICAgYm90dG9tX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX3djdHJpW2kscF92YWx1ZSA6PSBjb2VmKHN1bW1hcnkobW9kKSlbLCJQcig+fHp8KSJdWzJdXQogICAgYm90dG9tX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX3djdHJpW2ksQUlDYyA6PSBBSUNjKG1vZCldCiAgICAKICAgIHByaW50KHBhc3RlKGksIGxlbmd0aChib3R0b21fdmFyaWFibGVzKSwgc2VwID0gIi8iKSkKICAgICAgCiAgfQoKI2FkZCBjb2x1bW4gZm9yIHRob3NlIHRoYXQgZGlkbid0IGNvbnZlcmdlCmJvdHRvbV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl93Y3RyaSRjb252ZXJnZSA8LSBUCmJvdHRvbV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl93Y3RyaSRjb252ZXJnZVtjKDE0LCAyMywgMzMsIDQ5LCA1MSwgNTIsIDU2LCA1OCwgNjAsIDY1LCA3NiwgNzgsIDg5LCA5MywgOTgsIDEwNCwgMTA5LCAxMTIsIDExMywgMTE1LCAxMTkpXSA8LSBGCgojYWRkIGNvbHVtbiB0byBkZXNpZ25hdGUgcmVnaW9uIAogIGJvdHRvbV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl93Y3RyaSRyZWcgPC0gIndjdHJpIgoKYGBgCgpOb3csIEknbGwgbWVyZ2UgYWxsIGJvdHRvbSBjb2xvbml6YXRpb24gbW9kZWxzCmBgYHtyIG1lcmdlIGJvdHRvbSBjb2xvbml6YXRpb24gbW9kZWxzfQpib3R0b21fY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fYnlyZWdpb24gPC0gcmJpbmQoYm90dG9tX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX2FpLCBib3R0b21fY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fZWJzLCBib3R0b21fY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fZ21leCwgYm90dG9tX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX2dvYSwgYm90dG9tX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX25ldXMsIGJvdHRvbV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9uZXdmLCBib3R0b21fY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fc2EsIGJvdHRvbV9jb2xvbml6YXRpb25fbW9kZWxfY29tcGFyaXNvbl9zaGVsZiwgYm90dG9tX2NvbG9uaXphdGlvbl9tb2RlbF9jb21wYXJpc29uX3djdHJpKQpgYGAKCkJlc3QgYm90dG9tIGNvbG9uaXphdGlvbiBtb2RlbHMgcGVyIHJlZ2lvbgoKYGBge3IgYmVzdCBib3R0b20gY29sb25pemF0aW9uIG1vZGVscyBwZXIgcmVnaW9ufQpib3R0b21fY29sb25pemF0aW9uX21vZGVsX2NvbXBhcmlzb25fYnlyZWdpb24gJT4lCiAgZmlsdGVyKGNvbnZlcmdlID09IFRSVUUsICFncmVwbCgibWVhbiIsIHZhcmlhYmxlKSkgJT4lICNpZ25vcmluZyBtZWFuIGZvciBub3csIGFuZCBnZXQgcmlkIG9mIHRob3NlIHRoYXQgZGlkbid0IGNvbnZlcmdlCiAgZ3JvdXBfYnkocmVnKSAlPiUgI2dyb3VwIGJ5IHJlZ2lvbgogIGFycmFuZ2UoQUlDYykgJT4lICNhcnJhbmdlIGJ5IEFJQ2MKICB0b3BfbigtNSwgQUlDYykgI3Rha2UgNSBiZXN0IG1vZGVscyAobG93ZXN0IEFJQ2MpCiAgCmBgYAoKCioqKioqKioKI1N1cmZhY2UgZXh0aW5jdGlvbiBjb21wYXJpc29uIGJ5IHJlZ2lvbgpgYGB7ciBzdXJmYWNlIGV4dGluY3Rpb24gY29tcGFyaXNvbiBieSByZWdpb259CiNyZWdpb25zCgojYWkgKDEsIDcsIDEzLCAyMywgMzcsIDQwLCA1MCwgNTIsIDU2LCA2NSwgNzEsIDc0LCA3OCwgNzksIDgwLCA5MywgOTQsIDk5LCAxMDcsIDExOSwgMTIwLCAxMjEgZmFpbCB0byBjb252ZXJnZSkKc3VyZmFjZV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fYWkgPC0gYXMuZGF0YS50YWJsZShtYXRyaXgobnJvdyA9IGxlbmd0aChzdXJmYWNlX3ZhcmlhYmxlcykpKQpzdXJmYWNlX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9haVssIHZhcmlhYmxlOj1hcy5mYWN0b3IoVjEpXVssIGNvZWY6PWFzLm51bWVyaWMoVjEpXVssIHBfdmFsdWU6PWFzLm51bWVyaWMoVjEpXVssIEFJQ2M6PWFzLm51bWVyaWMoVjEpXQpzdXJmYWNlX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9haVssIFYxIDo9IE5VTExdCiAgCiAgZm9yIChpIGluIDE6bGVuZ3RoKHN1cmZhY2VfdmFyaWFibGVzKSl7CiAgICBtb2QgPC0gZ2xtZXIobm93X2V4dCB+IGdldChzdXJmYWNlX3ZhcmlhYmxlc1tpXSkgKyAoMXx5ZWFyX2ZhY3RvciksIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gc3BwX21hc3Rlcl96dGVtcFtyZWcgPT0gImFpIl0pCiAgICBzdXJmYWNlX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9haVtpLHZhcmlhYmxlIDo9IHN1cmZhY2VfdmFyaWFibGVzW2ldXQogICAgc3VyZmFjZV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fYWlbaSxjb2VmIDo9IGNvZWYoc3VtbWFyeShtb2QpKVssIkVzdGltYXRlIl1bMl1dCiAgICBzdXJmYWNlX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9haVtpLHBfdmFsdWUgOj0gY29lZihzdW1tYXJ5KG1vZCkpWywiUHIoPnx6fCkiXVsyXV0KICAgIHN1cmZhY2VfZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX2FpW2ksQUlDYyA6PSBBSUNjKG1vZCldCiAgICAKICAgIHByaW50KHBhc3RlKGksIGxlbmd0aChzdXJmYWNlX3ZhcmlhYmxlcyksIHNlcCA9ICIvIikpCiAgICAgIAogIH0KICAjYWRkIGNvbHVtbiBmb3IgdGhvc2UgdGhhdCBkaWRuJ3QgY29udmVyZ2UKICBzdXJmYWNlX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9haSRjb252ZXJnZSA8LSBUCiAgc3VyZmFjZV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fYWkkY29udmVyZ2VbYygxLCA3LCAxMywgMjMsIDM3LCA0MCwgNTAsIDUyLCA1NiwgNjUsIDcxLCA3NCwgNzgsIDc5LCA4MCwgOTMsIDk0LCA5OSwgMTA3LCAxMTksIDEyMCwgMTIxKV0gPC0gRgogIAogICNhZGQgY29sdW1uIHRvIGRlc2lnbmF0ZSByZWdpb24gCiAgc3VyZmFjZV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fYWkkcmVnIDwtICJhaSIKICAKI2VicyAoNCwgMTgsIDQxIGRpZCBub3QgY29udmVyZ2UpCgpzdXJmYWNlX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9lYnMgPC0gYXMuZGF0YS50YWJsZShtYXRyaXgobnJvdyA9IGxlbmd0aChzdXJmYWNlX3ZhcmlhYmxlcykpKQpzdXJmYWNlX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9lYnNbLCB2YXJpYWJsZTo9YXMuZmFjdG9yKFYxKV1bLCBjb2VmOj1hcy5udW1lcmljKFYxKV1bLCBwX3ZhbHVlOj1hcy5udW1lcmljKFYxKV1bLCBBSUNjOj1hcy5udW1lcmljKFYxKV0Kc3VyZmFjZV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fZWJzWywgVjEgOj0gTlVMTF0KICAKICBmb3IgKGkgaW4gMTpsZW5ndGgoc3VyZmFjZV92YXJpYWJsZXMpKXsKICAgIG1vZCA8LSBnbG1lcihub3dfZXh0IH4gZ2V0KHN1cmZhY2VfdmFyaWFibGVzW2ldKSArICgxfHllYXJfZmFjdG9yKSwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBzcHBfbWFzdGVyX3p0ZW1wW3JlZyA9PSAiZWJzIl0pCiAgICBzdXJmYWNlX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9lYnNbaSx2YXJpYWJsZSA6PSBzdXJmYWNlX3ZhcmlhYmxlc1tpXV0KICAgIHN1cmZhY2VfZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX2Vic1tpLGNvZWYgOj0gY29lZihzdW1tYXJ5KG1vZCkpWywiRXN0aW1hdGUiXVsyXV0KICAgIHN1cmZhY2VfZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX2Vic1tpLHBfdmFsdWUgOj0gY29lZihzdW1tYXJ5KG1vZCkpWywiUHIoPnx6fCkiXVsyXV0KICAgIHN1cmZhY2VfZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX2Vic1tpLEFJQ2MgOj0gQUlDYyhtb2QpXQogICAgCiAgICBwcmludChwYXN0ZShpLCBsZW5ndGgoc3VyZmFjZV92YXJpYWJsZXMpLCBzZXAgPSAiLyIpKQogICAgICAKICB9CiAgI2FkZCBjb2x1bW4gZm9yIHRob3NlIHRoYXQgZGlkbid0IGNvbnZlcmdlCiAgc3VyZmFjZV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fZWJzJGNvbnZlcmdlIDwtIFQKICBzdXJmYWNlX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9lYnMkY29udmVyZ2VbYyg0LCAxOCwgNDEpXSA8LSBGCiAgCiAgI2FkZCBjb2x1bW4gdG8gZGVzaWduYXRlIHJlZ2lvbiAKICBzdXJmYWNlX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9lYnMkcmVnIDwtICJlYnMiCiAgCiNnbWV4ICgxOjI0LCAzMSwgMzIsIDMzLCAzNCwgMzcsIDQwLCA0MSwgNDIsIDQ0LCA0NywgNTEsIDU0LCA1NSwgNTYsIDU3LCA2MSwgNjIsIDY0LCA3MSwgNzIsIDczLCA3OCwgODAsIDgxLCA5MSwgOTQsIDk1LCA5NiwgMTAwLCAxMDIsIDExNCwgMTE3ICBmYWlsIHRvIGNvbnZlcmdlKQoKc3VyZmFjZV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fZ21leCA8LSBhcy5kYXRhLnRhYmxlKG1hdHJpeChucm93ID0gbGVuZ3RoKHN1cmZhY2VfdmFyaWFibGVzKSkpCnN1cmZhY2VfZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX2dtZXhbLCB2YXJpYWJsZTo9YXMuZmFjdG9yKFYxKV1bLCBjb2VmOj1hcy5udW1lcmljKFYxKV1bLCBwX3ZhbHVlOj1hcy5udW1lcmljKFYxKV1bLCBBSUNjOj1hcy5udW1lcmljKFYxKV0Kc3VyZmFjZV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fZ21leFssIFYxIDo9IE5VTExdCiAgCiAgZm9yIChpIGluIDE6bGVuZ3RoKHN1cmZhY2VfdmFyaWFibGVzKSl7CiAgICBtb2QgPC0gZ2xtZXIobm93X2V4dCB+IGdldChzdXJmYWNlX3ZhcmlhYmxlc1tpXSkgKyAoMXx5ZWFyX2ZhY3RvciksIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gc3BwX21hc3Rlcl96dGVtcFtyZWcgPT0gImdtZXgiXSkKICAgIG1vZDEgPC0gZ2xtZXIobm93X2V4dCB+IGdldChzdXJmYWNlX3ZhcmlhYmxlc1tpXSkgKyAoMXx5ZWFyX2ZhY3RvciksIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gc3BwX21hc3Rlcl96dGVtcFtyZWcgPT0gImdtZXgiXSkKICAgIHN1cmZhY2VfZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX2dtZXhbaSx2YXJpYWJsZSA6PSBzdXJmYWNlX3ZhcmlhYmxlc1tpXV0KICAgIHN1cmZhY2VfZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX2dtZXhbaSxjb2VmIDo9IGNvZWYoc3VtbWFyeShtb2QpKVssIkVzdGltYXRlIl1bMl1dCiAgICBzdXJmYWNlX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9nbWV4W2kscF92YWx1ZSA6PSBjb2VmKHN1bW1hcnkobW9kKSlbLCJQcig+fHp8KSJdWzJdXQogICAgc3VyZmFjZV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fZ21leFtpLEFJQ2MgOj0gQUlDYyhtb2QpXQogICAgCiAgICBwcmludChwYXN0ZShpLCBsZW5ndGgoc3VyZmFjZV92YXJpYWJsZXMpLCBzZXAgPSAiLyIpKQogICAgICAKICB9CiAgI2FkZCBjb2x1bW4gZm9yIHRob3NlIHRoYXQgZGlkbid0IGNvbnZlcmdlCiAgc3VyZmFjZV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fZ21leCRjb252ZXJnZSA8LSBUCiAgc3VyZmFjZV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fZ21leCRjb252ZXJnZVtjKDE6MjQsIDMxLCAzMiwgMzMsIDM0LCAzNywgNDAsIDQxLCA0MiwgNDQsIDQ3LCA1MSwgNTQsIDU1LCA1NiwgNTcsIDYxLCA2MiwgNjQsIDcxLCA3MiwgNzMsIDc4LCA4MCwgODEsIDkxLCA5NCwgOTUsIDk2LCAxMDAsIDEwMiwgMTE0LCAxMTcpXSA8LSBGCiAgCiAgI2FkZCBjb2x1bW4gdG8gZGVzaWduYXRlIHJlZ2lvbiAKICBzdXJmYWNlX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9nbWV4JHJlZyA8LSAiZ21leCIKCiNnb2EgKDk5IGRvZXNuJ3QgY29udmVyZ2UpCgpzdXJmYWNlX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9nb2EgPC0gYXMuZGF0YS50YWJsZShtYXRyaXgobnJvdyA9IGxlbmd0aChzdXJmYWNlX3ZhcmlhYmxlcykpKQpzdXJmYWNlX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9nb2FbLCB2YXJpYWJsZTo9YXMuZmFjdG9yKFYxKV1bLCBjb2VmOj1hcy5udW1lcmljKFYxKV1bLCBwX3ZhbHVlOj1hcy5udW1lcmljKFYxKV1bLCBBSUNjOj1hcy5udW1lcmljKFYxKV0Kc3VyZmFjZV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fZ29hWywgVjEgOj0gTlVMTF0KICAKICBmb3IgKGkgaW4gMTpsZW5ndGgoc3VyZmFjZV92YXJpYWJsZXMpKXsKICAgIG1vZCA8LSBnbG1lcihub3dfZXh0IH4gZ2V0KHN1cmZhY2VfdmFyaWFibGVzW2ldKSArICgxfHllYXJfZmFjdG9yKSwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBzcHBfbWFzdGVyX3p0ZW1wW3JlZyA9PSAiZ29hIl0pCiAgICBzdXJmYWNlX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9nb2FbaSx2YXJpYWJsZSA6PSBzdXJmYWNlX3ZhcmlhYmxlc1tpXV0KICAgIHN1cmZhY2VfZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX2dvYVtpLGNvZWYgOj0gY29lZihzdW1tYXJ5KG1vZCkpWywiRXN0aW1hdGUiXVsyXV0KICAgIHN1cmZhY2VfZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX2dvYVtpLHBfdmFsdWUgOj0gY29lZihzdW1tYXJ5KG1vZCkpWywiUHIoPnx6fCkiXVsyXV0KICAgIHN1cmZhY2VfZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX2dvYVtpLEFJQ2MgOj0gQUlDYyhtb2QpXQogICAgCiAgICBwcmludChwYXN0ZShpLCBsZW5ndGgoc3VyZmFjZV92YXJpYWJsZXMpLCBzZXAgPSAiLyIpKQogICAgICAKICB9CiAgI2FkZCBjb2x1bW4gZm9yIHRob3NlIHRoYXQgZGlkbid0IGNvbnZlcmdlCiAgc3VyZmFjZV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fZ29hJGNvbnZlcmdlIDwtIFQKICBzdXJmYWNlX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9nb2EkY29udmVyZ2VbYyg5OSldIDwtIFQKICAKICAjYWRkIGNvbHVtbiB0byBkZXNpZ25hdGUgcmVnaW9uIAogIHN1cmZhY2VfZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX2dvYSRyZWcgPC0gImdvYSIKCiNuZXVzICgxLCA0LCA2LCA3LCAxMCwgMTEsIDE3LCAxOCwgMjIsIDI3LCAyOCwgMjksIDMxLCAzMywgMzQsIDM4LCA0MCwgIGZhaWxlZCB0byBjb252ZXJnZSkKIyoqKlNUQVJUIEhFUkUqKioKc3VyZmFjZV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fbmV1cyA8LSBhcy5kYXRhLnRhYmxlKG1hdHJpeChucm93ID0gbGVuZ3RoKHN1cmZhY2VfdmFyaWFibGVzKSkpCnN1cmZhY2VfZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX25ldXNbLCB2YXJpYWJsZTo9YXMuZmFjdG9yKFYxKV1bLCBjb2VmOj1hcy5udW1lcmljKFYxKV1bLCBwX3ZhbHVlOj1hcy5udW1lcmljKFYxKV1bLCBBSUNjOj1hcy5udW1lcmljKFYxKV0Kc3VyZmFjZV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fbmV1c1ssIFYxIDo9IE5VTExdCiAgCiAgZm9yIChpIGluIDE6bGVuZ3RoKHN1cmZhY2VfdmFyaWFibGVzKSl7CiAgICBtb2QgPC0gZ2xtZXIobm93X2V4dCB+IGdldChzdXJmYWNlX3ZhcmlhYmxlc1tpXSkgKyAoMXx5ZWFyX2ZhY3RvciksIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gc3BwX21hc3Rlcl96dGVtcFtyZWcgPT0gIm5ldXMiXSkKICAgIHN1cmZhY2VfZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX25ldXNbaSx2YXJpYWJsZSA6PSBzdXJmYWNlX3ZhcmlhYmxlc1tpXV0KICAgIHN1cmZhY2VfZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX25ldXNbaSxjb2VmIDo9IGNvZWYoc3VtbWFyeShtb2QpKVssIkVzdGltYXRlIl1bMl1dCiAgICBzdXJmYWNlX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9uZXVzW2kscF92YWx1ZSA6PSBjb2VmKHN1bW1hcnkobW9kKSlbLCJQcig+fHp8KSJdWzJdXQogICAgc3VyZmFjZV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fbmV1c1tpLEFJQ2MgOj0gQUlDYyhtb2QpXQogICAgCiAgICBwcmludChwYXN0ZShpLCBsZW5ndGgoc3VyZmFjZV92YXJpYWJsZXMpLCBzZXAgPSAiLyIpKQogICAgICAKICB9CiNhZGQgY29sdW1uIGZvciB0aG9zZSB0aGF0IGRpZG4ndCBjb252ZXJnZQpzdXJmYWNlX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9uZXVzJGNvbnZlcmdlIDwtIFQKc3VyZmFjZV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fbmV1cyRjb252ZXJnZVtjKDEsIDQsIDYsIDcsIDEwLCAxMSwgMTcsIDE4LCAyMiwgMjcsIDI4LCAyOSwgMzEsIDMzLCAzNCwgMzgsIDQwKV0gPC0gRgoKI2FkZCBjb2x1bW4gdG8gZGVzaWduYXRlIHJlZ2lvbiAKICBzdXJmYWNlX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9uZXVzJHJlZyA8LSAibmV1cyIKCiNuZXdmIChBTEwgZmFpbGVkIHRvIGNvbnZlcmdlIChhbGwgc2luZ3VsYXJpdGllcykgKQoKc3VyZmFjZV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fbmV3ZiA8LSBhcy5kYXRhLnRhYmxlKG1hdHJpeChucm93ID0gbGVuZ3RoKHN1cmZhY2VfdmFyaWFibGVzKSkpCnN1cmZhY2VfZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX25ld2ZbLCB2YXJpYWJsZTo9YXMuZmFjdG9yKFYxKV1bLCBjb2VmOj1hcy5udW1lcmljKFYxKV1bLCBwX3ZhbHVlOj1hcy5udW1lcmljKFYxKV1bLCBBSUNjOj1hcy5udW1lcmljKFYxKV0Kc3VyZmFjZV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fbmV3ZlssIFYxIDo9IE5VTExdCiAgCiAgZm9yIChpIGluIDE6bGVuZ3RoKHN1cmZhY2VfdmFyaWFibGVzKSl7CiAgICBtb2QgPC0gZ2xtZXIobm93X2V4dCB+IGdldChzdXJmYWNlX3ZhcmlhYmxlc1tpXSkgKyAoMXx5ZWFyX2ZhY3RvciksIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gc3BwX21hc3Rlcl96dGVtcFtyZWcgPT0gIm5ld2YiXSkKICAgIHN1cmZhY2VfZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX25ld2ZbaSx2YXJpYWJsZSA6PSBzdXJmYWNlX3ZhcmlhYmxlc1tpXV0KICAgIHN1cmZhY2VfZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX25ld2ZbaSxjb2VmIDo9IGNvZWYoc3VtbWFyeShtb2QpKVssIkVzdGltYXRlIl1bMl1dCiAgICBzdXJmYWNlX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9uZXdmW2kscF92YWx1ZSA6PSBjb2VmKHN1bW1hcnkobW9kKSlbLCJQcig+fHp8KSJdWzJdXQogICAgc3VyZmFjZV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fbmV3ZltpLEFJQ2MgOj0gQUlDYyhtb2QpXQogICAgCiAgICBwcmludChwYXN0ZShpLCBsZW5ndGgoc3VyZmFjZV92YXJpYWJsZXMpLCBzZXAgPSAiLyIpKQogICAgICAKICB9CgojYWRkIGNvbHVtbiBmb3IgdGhvc2UgdGhhdCBkaWRuJ3QgY29udmVyZ2UKc3VyZmFjZV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fbmV3ZiRjb252ZXJnZSA8LSBUCnN1cmZhY2VfZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX25ld2YkY29udmVyZ2VbYygxOjEyNCldIDwtIEYKCiNhZGQgY29sdW1uIHRvIGRlc2lnbmF0ZSByZWdpb24gCiAgc3VyZmFjZV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fbmV3ZiRyZWcgPC0gIm5ld2YiCgoKI3NoZWxmICg0IGRpZG4ndCBjb252ZXJnZSkKCnN1cmZhY2VfZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX3NoZWxmIDwtIGFzLmRhdGEudGFibGUobWF0cml4KG5yb3cgPSBsZW5ndGgoc3VyZmFjZV92YXJpYWJsZXMpKSkKc3VyZmFjZV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fc2hlbGZbLCB2YXJpYWJsZTo9YXMuZmFjdG9yKFYxKV1bLCBjb2VmOj1hcy5udW1lcmljKFYxKV1bLCBwX3ZhbHVlOj1hcy5udW1lcmljKFYxKV1bLCBBSUNjOj1hcy5udW1lcmljKFYxKV0Kc3VyZmFjZV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fc2hlbGZbLCBWMSA6PSBOVUxMXQogIAogIGZvciAoaSBpbiAxOmxlbmd0aChzdXJmYWNlX3ZhcmlhYmxlcykpewogICAgbW9kIDwtIGdsbWVyKG5vd19leHQgfiBnZXQoc3VyZmFjZV92YXJpYWJsZXNbaV0pICsgKDF8eWVhcl9mYWN0b3IpLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IHNwcF9tYXN0ZXJfenRlbXBbcmVnID09ICJzaGVsZiJdKQogICAgc3VyZmFjZV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fc2hlbGZbaSx2YXJpYWJsZSA6PSBzdXJmYWNlX3ZhcmlhYmxlc1tpXV0KICAgIHN1cmZhY2VfZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX3NoZWxmW2ksY29lZiA6PSBjb2VmKHN1bW1hcnkobW9kKSlbLCJFc3RpbWF0ZSJdWzJdXQogICAgc3VyZmFjZV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fc2hlbGZbaSxwX3ZhbHVlIDo9IGNvZWYoc3VtbWFyeShtb2QpKVssIlByKD58enwpIl1bMl1dCiAgICBzdXJmYWNlX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9zaGVsZltpLEFJQ2MgOj0gQUlDYyhtb2QpXQogICAgCiAgICBwcmludChwYXN0ZShpLCBsZW5ndGgoc3VyZmFjZV92YXJpYWJsZXMpLCBzZXAgPSAiLyIpKQogICAgICAKICB9CgojYWRkIGNvbHVtbiBmb3IgdGhvc2UgdGhhdCBkaWRuJ3QgY29udmVyZ2UKc3VyZmFjZV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fc2hlbGYkY29udmVyZ2UgPC0gVApzdXJmYWNlX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9zaGVsZiRjb252ZXJnZVtjKDQpXSA8LSBGCgojYWRkIGNvbHVtbiB0byBkZXNpZ25hdGUgcmVnaW9uIAogIHN1cmZhY2VfZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX3NoZWxmJHJlZyA8LSAic2hlbGYiCgoKI3NhICgyLCA1LCA2LCA3LDgsOSwxMCwxMSwxMiwxMywxNCwxNSwxNywgMTksIDIwLCAyMSwgMjIsIDMyLCA0MiwgNjQsIDczLCA4OSwgMTAxLCAxMDMsIDExMywgMTIyIGRpZG4ndCBjb252ZXJnZSkKCnN1cmZhY2VfZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX3NhIDwtIGFzLmRhdGEudGFibGUobWF0cml4KG5yb3cgPSBsZW5ndGgoc3VyZmFjZV92YXJpYWJsZXMpKSkKc3VyZmFjZV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fc2FbLCB2YXJpYWJsZTo9YXMuZmFjdG9yKFYxKV1bLCBjb2VmOj1hcy5udW1lcmljKFYxKV1bLCBwX3ZhbHVlOj1hcy5udW1lcmljKFYxKV1bLCBBSUNjOj1hcy5udW1lcmljKFYxKV0Kc3VyZmFjZV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fc2FbLCBWMSA6PSBOVUxMXQogIAogIGZvciAoaSBpbiAxOmxlbmd0aChzdXJmYWNlX3ZhcmlhYmxlcykpewogICAgbW9kIDwtIGdsbWVyKG5vd19leHQgfiBnZXQoc3VyZmFjZV92YXJpYWJsZXNbaV0pICsgKDF8eWVhcl9mYWN0b3IpLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IHNwcF9tYXN0ZXJfenRlbXBbcmVnID09ICJzYSJdKQogICAgc3VyZmFjZV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fc2FbaSx2YXJpYWJsZSA6PSBzdXJmYWNlX3ZhcmlhYmxlc1tpXV0KICAgIHN1cmZhY2VfZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX3NhW2ksY29lZiA6PSBjb2VmKHN1bW1hcnkobW9kKSlbLCJFc3RpbWF0ZSJdWzJdXQogICAgc3VyZmFjZV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fc2FbaSxwX3ZhbHVlIDo9IGNvZWYoc3VtbWFyeShtb2QpKVssIlByKD58enwpIl1bMl1dCiAgICBzdXJmYWNlX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9zYVtpLEFJQ2MgOj0gQUlDYyhtb2QpXQogICAgCiAgICBwcmludChwYXN0ZShpLCBsZW5ndGgoc3VyZmFjZV92YXJpYWJsZXMpLCBzZXAgPSAiLyIpKQogICAgICAKICB9CgojYWRkIGNvbHVtbiBmb3IgdGhvc2UgdGhhdCBkaWRuJ3QgY29udmVyZ2UKc3VyZmFjZV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fc2EkY29udmVyZ2UgPC0gVApzdXJmYWNlX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9zYSRjb252ZXJnZVtjKDIsIDUsIDYsIDcsOCw5LDEwLDExLDEyLDEzLDE0LDE1LDE3LCAxOSwgMjAsIDIxLCAyMiwgMzIsIDQyLCA2NCwgNzMsIDg5LCAxMDEsIDEwMywgMTEzLCAxMjIpXSA8LSBGCgojYWRkIGNvbHVtbiB0byBkZXNpZ25hdGUgcmVnaW9uIAogIHN1cmZhY2VfZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX3NhJHJlZyA8LSAic2EiCgoKI3djdHJpICg1LCA2LCA3LCAxMCwgMTQ6MjAsIDIxOjIzLCAyNywgMjksMjMwLCAzMSwgMzIsIDMzLCAzNCwgMzUsIDM2LCAzOSwgNDAsIDQyLCA0MywgNDQsIDQ1LCA0OCwgNTEsIDUyLCA1MywgNTQsIDU5LCA2MCwgNjEsIDYzLCA2NCwgNjYsIDY4Ojc1LCA3NywgNzk6ODAsIDgyLCA4MywgODQsIDg1LCA4NywgODgsIDg5LCA5MCwgOTEsIDkyLCA5NSwgOTYsIDk4LCA5OSwgMTAwLCAxMDIsIDEwMywgMTA0LCAxMDYsIDEwNywgMTA4LCAxMDksIDExMSwgMTEyLCAxMTMsIDExNCwgMTE2LCAxMTgsIDExOSwgMTIxLCAxMjIsIDEyMywgMTI0IGZhaWxlZCB0byBjb252ZXJnZSkKCnN1cmZhY2VfZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX3djdHJpIDwtIGFzLmRhdGEudGFibGUobWF0cml4KG5yb3cgPSBsZW5ndGgoc3VyZmFjZV92YXJpYWJsZXMpKSkKc3VyZmFjZV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fd2N0cmlbLCB2YXJpYWJsZTo9YXMuZmFjdG9yKFYxKV1bLCBjb2VmOj1hcy5udW1lcmljKFYxKV1bLCBwX3ZhbHVlOj1hcy5udW1lcmljKFYxKV1bLCBBSUNjOj1hcy5udW1lcmljKFYxKV0Kc3VyZmFjZV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fd2N0cmlbLCBWMSA6PSBOVUxMXQogIAogIGZvciAoaSBpbiAxOmxlbmd0aChzdXJmYWNlX3ZhcmlhYmxlcykpewogICAgbW9kIDwtIGdsbWVyKG5vd19leHQgfiBnZXQoc3VyZmFjZV92YXJpYWJsZXNbaV0pICsgKDF8eWVhcl9mYWN0b3IpLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IHNwcF9tYXN0ZXJfenRlbXBbcmVnID09ICJ3Y3RyaSJdKQogICAgc3VyZmFjZV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fd2N0cmlbaSx2YXJpYWJsZSA6PSBzdXJmYWNlX3ZhcmlhYmxlc1tpXV0KICAgIHN1cmZhY2VfZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX3djdHJpW2ksY29lZiA6PSBjb2VmKHN1bW1hcnkobW9kKSlbLCJFc3RpbWF0ZSJdWzJdXQogICAgc3VyZmFjZV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fd2N0cmlbaSxwX3ZhbHVlIDo9IGNvZWYoc3VtbWFyeShtb2QpKVssIlByKD58enwpIl1bMl1dCiAgICBzdXJmYWNlX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl93Y3RyaVtpLEFJQ2MgOj0gQUlDYyhtb2QpXQogICAgCiAgICBwcmludChwYXN0ZShpLCBsZW5ndGgoc3VyZmFjZV92YXJpYWJsZXMpLCBzZXAgPSAiLyIpKQogICAgICAKICB9CgojYWRkIGNvbHVtbiBmb3IgdGhvc2UgdGhhdCBkaWRuJ3QgY29udmVyZ2UKc3VyZmFjZV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fd2N0cmkkY29udmVyZ2UgPC0gVApzdXJmYWNlX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl93Y3RyaSRjb252ZXJnZVtjKDUsIDYsIDcsIDEwLCAxNDoyMCwgMjE6MjMsIDI3LCAyOSwyMzAsIDMxLCAzMiwgMzMsIDM0LCAzNSwgMzYsIDM5LCA0MCwgNDIsIDQzLCA0NCwgNDUsIDQ4LCA1MSwgNTIsIDUzLCA1NCwgNTksIDYwLCA2MSwgNjMsIDY0LCA2NiwgNjg6NzUsIDc3LCA3OTo4MCwgODIsIDgzLCA4NCwgODUsIDg3LCA4OCwgODksIDkwLCA5MSwgOTIsIDk1LCA5NiwgOTgsIDk5LCAxMDAsIDEwMiwgMTAzLCAxMDQsIDEwNiwgMTA3LCAxMDgsIDEwOSwgMTExLCAxMTIsIDExMywgMTE0LCAxMTYsIDExOCwgMTE5LCAxMjEsIDEyMiwgMTIzLCAxMjQpXSA8LSBGCgojYWRkIGNvbHVtbiB0byBkZXNpZ25hdGUgcmVnaW9uIAogIHN1cmZhY2VfZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX3djdHJpJHJlZyA8LSAid2N0cmkiCgpgYGAKCk5vdywgSSdsbCBtZXJnZSBhbGwgc3VyZmFjZSBleHRpbmN0aW9uIG1vZGVscwpgYGB7ciBtZXJnZSBzdXJmYWNlIGV4dGluY3Rpb24gbW9kZWxzfQpzdXJmYWNlX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9ieXJlZ2lvbiA8LSByYmluZChzdXJmYWNlX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9haSwgc3VyZmFjZV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fZWJzLCBzdXJmYWNlX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9nbWV4LCBzdXJmYWNlX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9nb2EsIHN1cmZhY2VfZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX25ldXMsIHN1cmZhY2VfZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX25ld2YsIHN1cmZhY2VfZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX3NhLCBzdXJmYWNlX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9zaGVsZiwgc3VyZmFjZV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fd2N0cmkpCmBgYAoKQmVzdCBzdXJmYWNlIGV4dGluY3Rpb24gbW9kZWxzIHBlciByZWdpb24KCmBgYHtyIGJlc3Qgc3VyZmFjZSBleHRpbmN0aW9uIG1vZGVscyBwZXIgcmVnaW9ufQpzdXJmYWNlX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9ieXJlZ2lvbiAlPiUKICBmaWx0ZXIoY29udmVyZ2UgPT0gVFJVRSwgIWdyZXBsKCJtZWFuIiwgdmFyaWFibGUpKSAlPiUgI2lnbm9yaW5nIG1lYW4gZm9yIG5vdywgYW5kIGdldCByaWQgb2YgdGhvc2UgdGhhdCBkaWRuJ3QgY29udmVyZ2UKICBncm91cF9ieShyZWcpICU+JSAjZ3JvdXAgYnkgcmVnaW9uCiAgYXJyYW5nZShBSUNjKSAlPiUgI2FycmFuZ2UgYnkgQUlDYwogIHRvcF9uKC01LCBBSUNjKSAjdGFrZSA1IGJlc3QgbW9kZWxzIChsb3dlc3QgQUlDYykKICAKYGBgCgoqKioqKioqCiNCb3R0b20gZXh0aW5jdGlvbiBjb21wYXJpc29uIGJ5IHJlZ2lvbgpgYGB7ciBib3R0b20gZXh0aW5jdGlvbiBjb21wYXJpc29uIGJ5IHJlZ2lvbn0KYm90dG9tX3ZhcmlhYmxlcyA8LSBjb2xuYW1lcyhzcHBfbWFzdGVyX3p0ZW1wWywxNjk6MjkyXSkKICAKI3JlZ2lvbnMKCiNhaSAoMTozLCAxNSwgMjQsIDQ0LCA0NSwgNDcsIDU1LCA1NyBmYWlsIHRvIGNvbnZlcmdlKQpib3R0b21fZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX2FpIDwtIGFzLmRhdGEudGFibGUobWF0cml4KG5yb3cgPSBsZW5ndGgoYm90dG9tX3ZhcmlhYmxlcykpKQpib3R0b21fZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX2FpWywgdmFyaWFibGU6PWFzLmZhY3RvcihWMSldWywgY29lZjo9YXMubnVtZXJpYyhWMSldWywgcF92YWx1ZTo9YXMubnVtZXJpYyhWMSldWywgQUlDYzo9YXMubnVtZXJpYyhWMSldCmJvdHRvbV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fYWlbLCBWMSA6PSBOVUxMXQogIAogIGZvciAoaSBpbiAxOmxlbmd0aChib3R0b21fdmFyaWFibGVzKSl7CiAgICBtb2QgPC0gZ2xtZXIobm93X2V4dCB+IGdldChib3R0b21fdmFyaWFibGVzW2ldKSArICgxfHllYXJfZmFjdG9yKSwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBzcHBfbWFzdGVyX3p0ZW1wW3JlZyA9PSAiYWkiXSkKICAgIGJvdHRvbV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fYWlbaSx2YXJpYWJsZSA6PSBib3R0b21fdmFyaWFibGVzW2ldXQogICAgYm90dG9tX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9haVtpLGNvZWYgOj0gY29lZihzdW1tYXJ5KG1vZCkpWywiRXN0aW1hdGUiXVsyXV0KICAgIGJvdHRvbV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fYWlbaSxwX3ZhbHVlIDo9IGNvZWYoc3VtbWFyeShtb2QpKVssIlByKD58enwpIl1bMl1dCiAgICBib3R0b21fZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX2FpW2ksQUlDYyA6PSBBSUNjKG1vZCldCiAgICAKICAgIHByaW50KHBhc3RlKGksIGxlbmd0aChib3R0b21fdmFyaWFibGVzKSwgc2VwID0gIi8iKSkKICAgICAgCiAgfQogICNhZGQgY29sdW1uIGZvciB0aG9zZSB0aGF0IGRpZG4ndCBjb252ZXJnZQogIGJvdHRvbV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fYWkkY29udmVyZ2UgPC0gVAogIGJvdHRvbV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fYWkkY29udmVyZ2VbYygxOjMsIDE1LCAyNCwgNDQsIDQ1LCA0NywgNTUsIDU3KV0gPC0gRgogIAogICNhZGQgY29sdW1uIHRvIGRlc2lnbmF0ZSByZWdpb24gCiAgYm90dG9tX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9haSRyZWcgPC0gImFpIgogIAojZWJzICgyMyBkaWQgbm90IGNvbnZlcmdlKQoKYm90dG9tX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9lYnMgPC0gYXMuZGF0YS50YWJsZShtYXRyaXgobnJvdyA9IGxlbmd0aChib3R0b21fdmFyaWFibGVzKSkpCmJvdHRvbV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fZWJzWywgdmFyaWFibGU6PWFzLmZhY3RvcihWMSldWywgY29lZjo9YXMubnVtZXJpYyhWMSldWywgcF92YWx1ZTo9YXMubnVtZXJpYyhWMSldWywgQUlDYzo9YXMubnVtZXJpYyhWMSldCmJvdHRvbV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fZWJzWywgVjEgOj0gTlVMTF0KICAKICBmb3IgKGkgaW4gMTpsZW5ndGgoYm90dG9tX3ZhcmlhYmxlcykpewogICAgbW9kIDwtIGdsbWVyKG5vd19leHQgfiBnZXQoYm90dG9tX3ZhcmlhYmxlc1tpXSkgKyAoMXx5ZWFyX2ZhY3RvciksIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gc3BwX21hc3Rlcl96dGVtcFtyZWcgPT0gImVicyJdKQogICAgYm90dG9tX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9lYnNbaSx2YXJpYWJsZSA6PSBib3R0b21fdmFyaWFibGVzW2ldXQogICAgYm90dG9tX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9lYnNbaSxjb2VmIDo9IGNvZWYoc3VtbWFyeShtb2QpKVssIkVzdGltYXRlIl1bMl1dCiAgICBib3R0b21fZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX2Vic1tpLHBfdmFsdWUgOj0gY29lZihzdW1tYXJ5KG1vZCkpWywiUHIoPnx6fCkiXVsyXV0KICAgIGJvdHRvbV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fZWJzW2ksQUlDYyA6PSBBSUNjKG1vZCldCiAgICAKICAgIHByaW50KHBhc3RlKGksIGxlbmd0aChib3R0b21fdmFyaWFibGVzKSwgc2VwID0gIi8iKSkKICAgICAgCiAgfQogICNhZGQgY29sdW1uIGZvciB0aG9zZSB0aGF0IGRpZG4ndCBjb252ZXJnZQogIGJvdHRvbV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fZWJzJGNvbnZlcmdlIDwtIFQKICBib3R0b21fZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX2VicyRjb252ZXJnZVtjKDIzKV0gPC0gRgogIAogICNhZGQgY29sdW1uIHRvIGRlc2lnbmF0ZSByZWdpb24gCiAgYm90dG9tX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9lYnMkcmVnIDwtICJlYnMiCiAgCiNnbWV4ICg1LCA2LCA3LCA4LCAxMywgMTUsIDE3LCAxOCwgMjAsIDIxLCAyMywgMjQsIDI1LCAyNywgMjgsIDMxLCAzMiwgMzQsIDM2LCA0MDo0NCwgNDY6NDgsIDUyLCA1NiwgNTcsIDYwLCA2MSwgNjMsIDY3LCA3MCwgNzUsIDgwLCA5MCwgOTIsIDk5LCAxMTAsIDExMywgIGZhaWwgdG8gY29udmVyZ2UpCgpib3R0b21fZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX2dtZXggPC0gYXMuZGF0YS50YWJsZShtYXRyaXgobnJvdyA9IGxlbmd0aChib3R0b21fdmFyaWFibGVzKSkpCmJvdHRvbV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fZ21leFssIHZhcmlhYmxlOj1hcy5mYWN0b3IoVjEpXVssIGNvZWY6PWFzLm51bWVyaWMoVjEpXVssIHBfdmFsdWU6PWFzLm51bWVyaWMoVjEpXVssIEFJQ2M6PWFzLm51bWVyaWMoVjEpXQpib3R0b21fZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX2dtZXhbLCBWMSA6PSBOVUxMXQogIAogIGZvciAoaSBpbiAxOmxlbmd0aChib3R0b21fdmFyaWFibGVzKSl7CiAgICBtb2QgPC0gZ2xtZXIobm93X2V4dCB+IGdldChib3R0b21fdmFyaWFibGVzW2ldKSArICgxfHllYXJfZmFjdG9yKSwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBzcHBfbWFzdGVyX3p0ZW1wW3JlZyA9PSAiZ21leCJdKQogICAgbW9kMSA8LSBnbG1lcihub3dfZXh0IH4gZ2V0KGJvdHRvbV92YXJpYWJsZXNbaV0pICsgKDF8eWVhcl9mYWN0b3IpLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IHNwcF9tYXN0ZXJfenRlbXBbcmVnID09ICJnbWV4Il0pCiAgICBib3R0b21fZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX2dtZXhbaSx2YXJpYWJsZSA6PSBib3R0b21fdmFyaWFibGVzW2ldXQogICAgYm90dG9tX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9nbWV4W2ksY29lZiA6PSBjb2VmKHN1bW1hcnkobW9kKSlbLCJFc3RpbWF0ZSJdWzJdXQogICAgYm90dG9tX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9nbWV4W2kscF92YWx1ZSA6PSBjb2VmKHN1bW1hcnkobW9kKSlbLCJQcig+fHp8KSJdWzJdXQogICAgYm90dG9tX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9nbWV4W2ksQUlDYyA6PSBBSUNjKG1vZCldCiAgICAKICAgIHByaW50KHBhc3RlKGksIGxlbmd0aChib3R0b21fdmFyaWFibGVzKSwgc2VwID0gIi8iKSkKICAgICAgCiAgfQogICNhZGQgY29sdW1uIGZvciB0aG9zZSB0aGF0IGRpZG4ndCBjb252ZXJnZQogIGJvdHRvbV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fZ21leCRjb252ZXJnZSA8LSBUCiAgYm90dG9tX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9nbWV4JGNvbnZlcmdlW2MoNSwgNiwgNywgOCwgMTMsIDE1LCAxNywgMTgsIDIwLCAyMSwgMjMsIDI0LCAyNSwgMjcsIDI4LCAzMSwgMzIsIDM0LCAzNiwgNDA6NDQsIDQ2OjQ4LCA1MiwgNTYsIDU3LCA2MCwgNjEsIDYzLCA2NywgNzAsIDc1LCA4MCwgOTAsIDkyLCA5OSwgMTEwLCAxMTMpXSA8LSBGCiAgCiAgI2FkZCBjb2x1bW4gdG8gZGVzaWduYXRlIHJlZ2lvbiAKICBib3R0b21fZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX2dtZXgkcmVnIDwtICJnbWV4IgoKI2dvYSAoNjIgZG9lc24ndCBjb252ZXJnZSkKCmJvdHRvbV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fZ29hIDwtIGFzLmRhdGEudGFibGUobWF0cml4KG5yb3cgPSBsZW5ndGgoYm90dG9tX3ZhcmlhYmxlcykpKQpib3R0b21fZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX2dvYVssIHZhcmlhYmxlOj1hcy5mYWN0b3IoVjEpXVssIGNvZWY6PWFzLm51bWVyaWMoVjEpXVssIHBfdmFsdWU6PWFzLm51bWVyaWMoVjEpXVssIEFJQ2M6PWFzLm51bWVyaWMoVjEpXQpib3R0b21fZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX2dvYVssIFYxIDo9IE5VTExdCiAgCiAgZm9yIChpIGluIDE6bGVuZ3RoKGJvdHRvbV92YXJpYWJsZXMpKXsKICAgIG1vZCA8LSBnbG1lcihub3dfZXh0IH4gZ2V0KGJvdHRvbV92YXJpYWJsZXNbaV0pICsgKDF8eWVhcl9mYWN0b3IpLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IHNwcF9tYXN0ZXJfenRlbXBbcmVnID09ICJnb2EiXSkKICAgIGJvdHRvbV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fZ29hW2ksdmFyaWFibGUgOj0gYm90dG9tX3ZhcmlhYmxlc1tpXV0KICAgIGJvdHRvbV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fZ29hW2ksY29lZiA6PSBjb2VmKHN1bW1hcnkobW9kKSlbLCJFc3RpbWF0ZSJdWzJdXQogICAgYm90dG9tX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9nb2FbaSxwX3ZhbHVlIDo9IGNvZWYoc3VtbWFyeShtb2QpKVssIlByKD58enwpIl1bMl1dCiAgICBib3R0b21fZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX2dvYVtpLEFJQ2MgOj0gQUlDYyhtb2QpXQogICAgCiAgICBwcmludChwYXN0ZShpLCBsZW5ndGgoYm90dG9tX3ZhcmlhYmxlcyksIHNlcCA9ICIvIikpCiAgICAgIAogIH0KICAjYWRkIGNvbHVtbiBmb3IgdGhvc2UgdGhhdCBkaWRuJ3QgY29udmVyZ2UKICBib3R0b21fZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX2dvYSRjb252ZXJnZSA8LSBUCiAgYm90dG9tX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9nb2EkY29udmVyZ2VbYyg2MildIDwtIFQKICAKICAjYWRkIGNvbHVtbiB0byBkZXNpZ25hdGUgcmVnaW9uIAogIGJvdHRvbV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fZ29hJHJlZyA8LSAiZ29hIgoKI25ldXMgKDEsIDQsIDksIDEwLCAxMiwgMTY6MTksIDIyLCAyNCwgMjcsIDI4LCAyOSwgMzIsIDMzLCAzNiwgMzcsIDM5LCA0MCwgNDMsICBmYWlsZWQgdG8gY29udmVyZ2UpCgpib3R0b21fZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX25ldXMgPC0gYXMuZGF0YS50YWJsZShtYXRyaXgobnJvdyA9IGxlbmd0aChib3R0b21fdmFyaWFibGVzKSkpCmJvdHRvbV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fbmV1c1ssIHZhcmlhYmxlOj1hcy5mYWN0b3IoVjEpXVssIGNvZWY6PWFzLm51bWVyaWMoVjEpXVssIHBfdmFsdWU6PWFzLm51bWVyaWMoVjEpXVssIEFJQ2M6PWFzLm51bWVyaWMoVjEpXQpib3R0b21fZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX25ldXNbLCBWMSA6PSBOVUxMXQogIAogIGZvciAoaSBpbiAxOmxlbmd0aChib3R0b21fdmFyaWFibGVzKSl7CiAgICBtb2QgPC0gZ2xtZXIobm93X2V4dCB+IGdldChib3R0b21fdmFyaWFibGVzW2ldKSArICgxfHllYXJfZmFjdG9yKSwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBzcHBfbWFzdGVyX3p0ZW1wW3JlZyA9PSAibmV1cyJdKQogICAgYm90dG9tX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9uZXVzW2ksdmFyaWFibGUgOj0gYm90dG9tX3ZhcmlhYmxlc1tpXV0KICAgIGJvdHRvbV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fbmV1c1tpLGNvZWYgOj0gY29lZihzdW1tYXJ5KG1vZCkpWywiRXN0aW1hdGUiXVsyXV0KICAgIGJvdHRvbV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fbmV1c1tpLHBfdmFsdWUgOj0gY29lZihzdW1tYXJ5KG1vZCkpWywiUHIoPnx6fCkiXVsyXV0KICAgIGJvdHRvbV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fbmV1c1tpLEFJQ2MgOj0gQUlDYyhtb2QpXQogICAgCiAgICBwcmludChwYXN0ZShpLCBsZW5ndGgoYm90dG9tX3ZhcmlhYmxlcyksIHNlcCA9ICIvIikpCiAgICAgIAogIH0KI2FkZCBjb2x1bW4gZm9yIHRob3NlIHRoYXQgZGlkbid0IGNvbnZlcmdlCmJvdHRvbV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fbmV1cyRjb252ZXJnZSA8LSBUCmJvdHRvbV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fbmV1cyRjb252ZXJnZVtjKDEsIDQsIDksIDEwLCAxMiwgMTY6MTksIDIyLCAyNCwgMjcsIDI4LCAyOSwgMzIsIDMzLCAzNiwgMzcsIDM5LCA0MCwgNDMpXSA8LSBGCgojYWRkIGNvbHVtbiB0byBkZXNpZ25hdGUgcmVnaW9uIAogIGJvdHRvbV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fbmV1cyRyZWcgPC0gIm5ldXMiCgojbmV3ZiAoQUxMIGZhaWxlZCB0byBjb252ZXJnZSAoYWxsIHNpbmd1bGFyaXRpZXMpICkKCmJvdHRvbV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fbmV3ZiA8LSBhcy5kYXRhLnRhYmxlKG1hdHJpeChucm93ID0gbGVuZ3RoKGJvdHRvbV92YXJpYWJsZXMpKSkKYm90dG9tX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9uZXdmWywgdmFyaWFibGU6PWFzLmZhY3RvcihWMSldWywgY29lZjo9YXMubnVtZXJpYyhWMSldWywgcF92YWx1ZTo9YXMubnVtZXJpYyhWMSldWywgQUlDYzo9YXMubnVtZXJpYyhWMSldCmJvdHRvbV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fbmV3ZlssIFYxIDo9IE5VTExdCiAgCiAgZm9yIChpIGluIDE6bGVuZ3RoKGJvdHRvbV92YXJpYWJsZXMpKXsKICAgIG1vZCA8LSBnbG1lcihub3dfZXh0IH4gZ2V0KGJvdHRvbV92YXJpYWJsZXNbaV0pICsgKDF8eWVhcl9mYWN0b3IpLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IHNwcF9tYXN0ZXJfenRlbXBbcmVnID09ICJuZXdmIl0pCiAgICBib3R0b21fZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX25ld2ZbaSx2YXJpYWJsZSA6PSBib3R0b21fdmFyaWFibGVzW2ldXQogICAgYm90dG9tX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9uZXdmW2ksY29lZiA6PSBjb2VmKHN1bW1hcnkobW9kKSlbLCJFc3RpbWF0ZSJdWzJdXQogICAgYm90dG9tX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9uZXdmW2kscF92YWx1ZSA6PSBjb2VmKHN1bW1hcnkobW9kKSlbLCJQcig+fHp8KSJdWzJdXQogICAgYm90dG9tX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9uZXdmW2ksQUlDYyA6PSBBSUNjKG1vZCldCiAgICAKICAgIHByaW50KHBhc3RlKGksIGxlbmd0aChib3R0b21fdmFyaWFibGVzKSwgc2VwID0gIi8iKSkKICAgICAgCiAgfQoKI2FkZCBjb2x1bW4gZm9yIHRob3NlIHRoYXQgZGlkbid0IGNvbnZlcmdlCmJvdHRvbV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fbmV3ZiRjb252ZXJnZSA8LSBUCmJvdHRvbV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fbmV3ZiRjb252ZXJnZVtjKDE6MTI0KV0gPC0gRgoKI2FkZCBjb2x1bW4gdG8gZGVzaWduYXRlIHJlZ2lvbiAKICBib3R0b21fZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX25ld2YkcmVnIDwtICJuZXdmIgoKCiNzaGVsZiAobm9uZSBkaWRuJ3QgY29udmVyZ2UpCgpib3R0b21fZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX3NoZWxmIDwtIGFzLmRhdGEudGFibGUobWF0cml4KG5yb3cgPSBsZW5ndGgoYm90dG9tX3ZhcmlhYmxlcykpKQpib3R0b21fZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX3NoZWxmWywgdmFyaWFibGU6PWFzLmZhY3RvcihWMSldWywgY29lZjo9YXMubnVtZXJpYyhWMSldWywgcF92YWx1ZTo9YXMubnVtZXJpYyhWMSldWywgQUlDYzo9YXMubnVtZXJpYyhWMSldCmJvdHRvbV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fc2hlbGZbLCBWMSA6PSBOVUxMXQogIAogIGZvciAoaSBpbiAxOmxlbmd0aChib3R0b21fdmFyaWFibGVzKSl7CiAgICBtb2QgPC0gZ2xtZXIobm93X2V4dCB+IGdldChib3R0b21fdmFyaWFibGVzW2ldKSArICgxfHllYXJfZmFjdG9yKSwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBzcHBfbWFzdGVyX3p0ZW1wW3JlZyA9PSAic2hlbGYiXSkKICAgIGJvdHRvbV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fc2hlbGZbaSx2YXJpYWJsZSA6PSBib3R0b21fdmFyaWFibGVzW2ldXQogICAgYm90dG9tX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9zaGVsZltpLGNvZWYgOj0gY29lZihzdW1tYXJ5KG1vZCkpWywiRXN0aW1hdGUiXVsyXV0KICAgIGJvdHRvbV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fc2hlbGZbaSxwX3ZhbHVlIDo9IGNvZWYoc3VtbWFyeShtb2QpKVssIlByKD58enwpIl1bMl1dCiAgICBib3R0b21fZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX3NoZWxmW2ksQUlDYyA6PSBBSUNjKG1vZCldCiAgICAKICAgIHByaW50KHBhc3RlKGksIGxlbmd0aChib3R0b21fdmFyaWFibGVzKSwgc2VwID0gIi8iKSkKICAgICAgCiAgfQoKI2FkZCBjb2x1bW4gZm9yIHRob3NlIHRoYXQgZGlkbid0IGNvbnZlcmdlCmJvdHRvbV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fc2hlbGYkY29udmVyZ2UgPC0gVAoKI2FkZCBjb2x1bW4gdG8gZGVzaWduYXRlIHJlZ2lvbiAKICBib3R0b21fZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX3NoZWxmJHJlZyA8LSAic2hlbGYiCgoKI3NhICgxMiwgMzEsIDM1LCA1NSwgNjMsIDcyLCA4MiwgODcsIDkyLCA5NiwgMTIzIGRpZG4ndCBjb252ZXJnZSkKCmJvdHRvbV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fc2EgPC0gYXMuZGF0YS50YWJsZShtYXRyaXgobnJvdyA9IGxlbmd0aChib3R0b21fdmFyaWFibGVzKSkpCmJvdHRvbV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fc2FbLCB2YXJpYWJsZTo9YXMuZmFjdG9yKFYxKV1bLCBjb2VmOj1hcy5udW1lcmljKFYxKV1bLCBwX3ZhbHVlOj1hcy5udW1lcmljKFYxKV1bLCBBSUNjOj1hcy5udW1lcmljKFYxKV0KYm90dG9tX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9zYVssIFYxIDo9IE5VTExdCiAgCiAgZm9yIChpIGluIDE6bGVuZ3RoKGJvdHRvbV92YXJpYWJsZXMpKXsKICAgIG1vZCA8LSBnbG1lcihub3dfZXh0IH4gZ2V0KGJvdHRvbV92YXJpYWJsZXNbaV0pICsgKDF8eWVhcl9mYWN0b3IpLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IHNwcF9tYXN0ZXJfenRlbXBbcmVnID09ICJzYSJdKQogICAgYm90dG9tX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9zYVtpLHZhcmlhYmxlIDo9IGJvdHRvbV92YXJpYWJsZXNbaV1dCiAgICBib3R0b21fZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX3NhW2ksY29lZiA6PSBjb2VmKHN1bW1hcnkobW9kKSlbLCJFc3RpbWF0ZSJdWzJdXQogICAgYm90dG9tX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9zYVtpLHBfdmFsdWUgOj0gY29lZihzdW1tYXJ5KG1vZCkpWywiUHIoPnx6fCkiXVsyXV0KICAgIGJvdHRvbV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fc2FbaSxBSUNjIDo9IEFJQ2MobW9kKV0KICAgIAogICAgcHJpbnQocGFzdGUoaSwgbGVuZ3RoKGJvdHRvbV92YXJpYWJsZXMpLCBzZXAgPSAiLyIpKQogICAgICAKICB9CgojYWRkIGNvbHVtbiBmb3IgdGhvc2UgdGhhdCBkaWRuJ3QgY29udmVyZ2UKYm90dG9tX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9zYSRjb252ZXJnZSA8LSBUCmJvdHRvbV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fc2EkY29udmVyZ2VbYygxMiwgMzEsIDM1LCA1NSwgNjMsIDcyLCA4MiwgODcsIDkyLCA5NiwgMTIzKV0gPC0gRgoKI2FkZCBjb2x1bW4gdG8gZGVzaWduYXRlIHJlZ2lvbiAKICBib3R0b21fZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX3NhJHJlZyA8LSAic2EiCgoKI3djdHJpICgxLCAyLCAzLCA1OjEwLCAxNToyMCwgMjU6MjksIDM2LCAzODo0MiwgNDQsIDQ3LCA0OSwgNTIsIDU0LCA1NSwgNTYsIDU4OjY1LCA2ODo3NSwgNzk6IDgzLCA4NTo4NywgODksIDkwLCA5NDo5OCwgMTAwLCAxMDI6MTA2LCAxMDk6MTExLCAxMTM6MTE2LCAxMTksIDEyMSwgMTI0IGZhaWxlZCB0byBjb252ZXJnZSkKCmJvdHRvbV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fd2N0cmkgPC0gYXMuZGF0YS50YWJsZShtYXRyaXgobnJvdyA9IGxlbmd0aChib3R0b21fdmFyaWFibGVzKSkpCmJvdHRvbV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fd2N0cmlbLCB2YXJpYWJsZTo9YXMuZmFjdG9yKFYxKV1bLCBjb2VmOj1hcy5udW1lcmljKFYxKV1bLCBwX3ZhbHVlOj1hcy5udW1lcmljKFYxKV1bLCBBSUNjOj1hcy5udW1lcmljKFYxKV0KYm90dG9tX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl93Y3RyaVssIFYxIDo9IE5VTExdCiAgCiAgZm9yIChpIGluIDE6bGVuZ3RoKGJvdHRvbV92YXJpYWJsZXMpKXsKICAgIG1vZCA8LSBnbG1lcihub3dfZXh0IH4gZ2V0KGJvdHRvbV92YXJpYWJsZXNbaV0pICsgKDF8eWVhcl9mYWN0b3IpLCBmYW1pbHkgPSBiaW5vbWlhbCwgZGF0YSA9IHNwcF9tYXN0ZXJfenRlbXBbcmVnID09ICJ3Y3RyaSJdKQogICAgYm90dG9tX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl93Y3RyaVtpLHZhcmlhYmxlIDo9IGJvdHRvbV92YXJpYWJsZXNbaV1dCiAgICBib3R0b21fZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX3djdHJpW2ksY29lZiA6PSBjb2VmKHN1bW1hcnkobW9kKSlbLCJFc3RpbWF0ZSJdWzJdXQogICAgYm90dG9tX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl93Y3RyaVtpLHBfdmFsdWUgOj0gY29lZihzdW1tYXJ5KG1vZCkpWywiUHIoPnx6fCkiXVsyXV0KICAgIGJvdHRvbV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fd2N0cmlbaSxBSUNjIDo9IEFJQ2MobW9kKV0KICAgIAogICAgcHJpbnQocGFzdGUoaSwgbGVuZ3RoKGJvdHRvbV92YXJpYWJsZXMpLCBzZXAgPSAiLyIpKQogICAgICAKICB9CgojYWRkIGNvbHVtbiBmb3IgdGhvc2UgdGhhdCBkaWRuJ3QgY29udmVyZ2UKYm90dG9tX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl93Y3RyaSRjb252ZXJnZSA8LSBUCmJvdHRvbV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fd2N0cmkkY29udmVyZ2VbYygxLCAyLCAzLCA1OjEwLCAxNToyMCwgMjU6MjksIDM2LCAzODo0MiwgNDQsIDQ3LCA0OSwgNTIsIDU0LCA1NSwgNTYsIDU4OjY1LCA2ODo3NSwgNzk6IDgzLCA4NTo4NywgODksIDkwLCA5NDo5OCwgMTAwLCAxMDI6MTA2LCAxMDk6MTExLCAxMTM6MTE2LCAxMTksIDEyMSwgMTI0KV0gPC0gRgoKI2FkZCBjb2x1bW4gdG8gZGVzaWduYXRlIHJlZ2lvbiAKICBib3R0b21fZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX3djdHJpJHJlZyA8LSAid2N0cmkiCgpgYGAKCk5vdywgSSdsbCBtZXJnZSBhbGwgYm90dG9tIGV4dGluY3Rpb24gbW9kZWxzCmBgYHtyIG1lcmdlIGJvdHRvbSBleHRpbmN0aW9uIG1vZGVsc30KYm90dG9tX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9ieXJlZ2lvbiA8LSByYmluZChib3R0b21fZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX2FpLCBib3R0b21fZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX2VicywgYm90dG9tX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9nbWV4LCBib3R0b21fZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX2dvYSwgYm90dG9tX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9uZXVzLCBib3R0b21fZXh0aW5jdGlvbl9tb2RlbF9jb21wYXJpc29uX25ld2YsIGJvdHRvbV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fc2EsIGJvdHRvbV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fc2hlbGYsIGJvdHRvbV9leHRpbmN0aW9uX21vZGVsX2NvbXBhcmlzb25fd2N0cmkpCmBgYAoKQmVzdCBib3R0b20gZXh0aW5jdGlvbiBtb2RlbHMgcGVyIHJlZ2lvbgoKYGBge3IgYmVzdCBib3R0b20gZXh0aW5jdGlvbiBtb2RlbHMgcGVyIHJlZ2lvbn0KYm90dG9tX2V4dGluY3Rpb25fbW9kZWxfY29tcGFyaXNvbl9ieXJlZ2lvbiAlPiUKICBmaWx0ZXIoY29udmVyZ2UgPT0gVFJVRSwgIWdyZXBsKCJtZWFuIiwgdmFyaWFibGUpKSAlPiUgI2lnbm9yaW5nIG1lYW4gZm9yIG5vdywgYW5kIGdldCByaWQgb2YgdGhvc2UgdGhhdCBkaWRuJ3QgY29udmVyZ2UKICBncm91cF9ieShyZWcpICU+JSAjZ3JvdXAgYnkgcmVnaW9uCiAgYXJyYW5nZShBSUNjKSAlPiUgI2FycmFuZ2UgYnkgQUlDYwogIHRvcF9uKC01LCBBSUNjKSAjdGFrZSA1IGJlc3QgbW9kZWxzIChsb3dlc3QgQUlDYykKICAKYGBg